optconfig 0.4.4 → 0.4.5
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/lib/optconfig.rb +9 -14
- data/spec/optconfig_spec.rb +1006 -0
- metadata +38 -43
data/lib/optconfig.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
#
|
2
|
-
# Copyright (C) 2004-
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# Copyright (C) 2004-2011 TOMITA Masahiro
|
3
3
|
# mailto:tommy@tmtm.org
|
4
4
|
#
|
5
5
|
# = OptConfig
|
@@ -13,16 +13,11 @@
|
|
13
13
|
# * usage に使用する文字列を自動的に生成します。
|
14
14
|
# * オプションの引数の形式を指定できます。
|
15
15
|
#
|
16
|
-
# == Download
|
17
|
-
# * http://rubyforge.org/frs/?group_id=4777
|
18
|
-
# * http://tmtm.org/downloads/ruby/optconfig/
|
19
|
-
#
|
20
|
-
# == Required
|
21
|
-
# * StringValidator http://stringvalidator.rubyforge.org/
|
22
|
-
#
|
23
16
|
# == Install
|
24
|
-
# $
|
25
|
-
#
|
17
|
+
# $ gem install optconfig
|
18
|
+
#
|
19
|
+
# == Repository
|
20
|
+
# https://github.com/tmtm/optconfig
|
26
21
|
#
|
27
22
|
# == Usage
|
28
23
|
# require "optconfig"
|
@@ -149,7 +144,7 @@ class OptConfig
|
|
149
144
|
@option_seq = []
|
150
145
|
@options = {}
|
151
146
|
@file = default_attr[:file]
|
152
|
-
@section = default_attr[:section]
|
147
|
+
@section = default_attr[:section] && [default_attr[:section]].flatten
|
153
148
|
@stop_at_non_option_argument = default_attr[:stop_at_non_option_argument]
|
154
149
|
@ignore_unknown_file_option = default_attr.key?(:ignore_unknown_file_option) ? default_attr[:ignore_unknown_file_option] : true
|
155
150
|
@obsolete_behavior = false
|
@@ -190,7 +185,7 @@ class OptConfig
|
|
190
185
|
@option_seq.clear
|
191
186
|
option.each do |k,v|
|
192
187
|
v = [v] unless v.is_a? Array
|
193
|
-
arg = k.
|
188
|
+
arg = k.is_a?(Array) ? k : [k]
|
194
189
|
arg.push({:format=>v[0], :default=>v[1]})
|
195
190
|
opt = Option.new *arg
|
196
191
|
opt.name.each do |n|
|
@@ -272,7 +267,7 @@ class OptConfig
|
|
272
267
|
cur_sect = $1
|
273
268
|
next
|
274
269
|
end
|
275
|
-
if @section.nil? or @section.empty? or @section.
|
270
|
+
if @section.nil? or @section.empty? or @section.include? cur_sect
|
276
271
|
name, value = line.split(/\s*=\s*|\s+/, 2)
|
277
272
|
begin
|
278
273
|
name, = long_option name, false
|
@@ -0,0 +1,1006 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require "tempfile"
|
3
|
+
|
4
|
+
require "#{File.dirname __FILE__}/../lib/optconfig"
|
5
|
+
|
6
|
+
describe '未知のオプション指定' do
|
7
|
+
it 'UnknownOption' do
|
8
|
+
opt = OptConfig.new
|
9
|
+
opt.option "s", "long"
|
10
|
+
proc{opt.parse(["-z"])}.should raise_error(OptConfig::UnknownOption, 'unknown option: z')
|
11
|
+
proc{opt.parse(["--hoge"])}.should raise_error(OptConfig::UnknownOption, 'unknown option: hoge')
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '短いオプション名で :argument=>false の場合' do
|
16
|
+
before do
|
17
|
+
@opt = OptConfig.new
|
18
|
+
@opt.option "s", :argument=>false
|
19
|
+
@opt.option "x", :argument=>false
|
20
|
+
end
|
21
|
+
it 'オプション指定で true' do
|
22
|
+
@opt.parse(["-s"])
|
23
|
+
@opt["s"].should == true
|
24
|
+
end
|
25
|
+
it 'オプションの次の引数はただの引数' do
|
26
|
+
arg = ["-s", "hoge"]
|
27
|
+
@opt.parse! arg
|
28
|
+
@opt["s"].should == true
|
29
|
+
arg.should == ["hoge"]
|
30
|
+
end
|
31
|
+
it 'オプション名に続いて文字列がある場合は別のオプション' do
|
32
|
+
@opt.parse ["-sx"]
|
33
|
+
@opt["s"].should == true
|
34
|
+
@opt["x"].should == true
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '長いオプション名で :argument=>false の場合' do
|
39
|
+
before do
|
40
|
+
@opt = OptConfig.new
|
41
|
+
@opt.option "long", :argument=>false
|
42
|
+
end
|
43
|
+
it 'オプション指定で true' do
|
44
|
+
@opt.parse(["--long"])
|
45
|
+
@opt["long"].should == true
|
46
|
+
end
|
47
|
+
it 'オプションの次の引数はただの引数' do
|
48
|
+
arg = ["--long", "hoge"]
|
49
|
+
@opt.parse! arg
|
50
|
+
@opt["long"].should == true
|
51
|
+
arg.should == ["hoge"]
|
52
|
+
end
|
53
|
+
it '「=」でオプション引数指定は UnnecessaryArgument' do
|
54
|
+
proc{@opt.parse(["--long=hoge"])}.should raise_error(OptConfig::UnnecessaryArgument)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe '短いオプション名で :argument=>true の場合' do
|
59
|
+
before do
|
60
|
+
@opt = OptConfig.new
|
61
|
+
@opt.option "s", :argument=>true
|
62
|
+
@opt.option "x", :argument=>false
|
63
|
+
end
|
64
|
+
it '引数がない指定で ArgumentRequired' do
|
65
|
+
proc{@opt.parse ["-s"]}.should raise_error(OptConfig::ArgumentRequired, "argument required: s")
|
66
|
+
end
|
67
|
+
it 'オプションの次の引数がオプション引数' do
|
68
|
+
arg = ["-s", "hoge", "fuga"]
|
69
|
+
@opt.parse! arg
|
70
|
+
@opt["s"].should == "hoge"
|
71
|
+
arg.should == ["fuga"]
|
72
|
+
end
|
73
|
+
it 'オプション名に続いて文字列がある場合はオプション引数' do
|
74
|
+
arg = ["-shoge", "fuga"]
|
75
|
+
@opt.parse! arg
|
76
|
+
@opt["s"].should == "hoge"
|
77
|
+
arg.should == ["fuga"]
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe '長いオプション名で :argument=>true の場合' do
|
82
|
+
before do
|
83
|
+
@opt = OptConfig.new
|
84
|
+
@opt.option "long", :argument=>true
|
85
|
+
end
|
86
|
+
it '引数がない指定で ArgumentRequired' do
|
87
|
+
proc{@opt.parse ["--long"]}.should raise_error(OptConfig::ArgumentRequired, "argument required: long")
|
88
|
+
end
|
89
|
+
it 'オプションの次の引数がオプション引数' do
|
90
|
+
arg = ["--long", "hoge", "fuga"]
|
91
|
+
@opt.parse! arg
|
92
|
+
@opt["long"].should == "hoge"
|
93
|
+
arg.should == ["fuga"]
|
94
|
+
end
|
95
|
+
it '「=」でオプション引数指定可能' do
|
96
|
+
arg = ["--long=hoge", "fuga"]
|
97
|
+
@opt.parse! arg
|
98
|
+
@opt["long"].should == "hoge"
|
99
|
+
arg.should == ["fuga"]
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe '短いオプション名で :argument=>:optional の場合' do
|
104
|
+
before do
|
105
|
+
@opt = OptConfig.new
|
106
|
+
@opt.option "s", :argument=>:optional
|
107
|
+
end
|
108
|
+
it '次の引数がない指定で true' do
|
109
|
+
@opt.parse ["-s"]
|
110
|
+
@opt["s"].should == true
|
111
|
+
end
|
112
|
+
it 'オプションの次の引数が普通の引数' do
|
113
|
+
arg = ["-s", "hoge"]
|
114
|
+
@opt.parse! arg
|
115
|
+
@opt["s"].should == true
|
116
|
+
arg.should == ["hoge"]
|
117
|
+
end
|
118
|
+
it 'オプション名に続いて文字列がある場合はオプション引数' do
|
119
|
+
arg = ["-shoge", "fuga"]
|
120
|
+
@opt.parse! arg
|
121
|
+
@opt["s"].should == "hoge"
|
122
|
+
arg.should == ["fuga"]
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe '長いオプション名で :argument=>:optional の場合' do
|
127
|
+
before do
|
128
|
+
@opt = OptConfig.new
|
129
|
+
@opt.option "long", :argument=>:optional
|
130
|
+
end
|
131
|
+
it '次の引数がない指定で true' do
|
132
|
+
@opt.parse ["--long"]
|
133
|
+
@opt["long"].should == true
|
134
|
+
end
|
135
|
+
it 'オプションの次の引数が普通の引数' do
|
136
|
+
arg = ["--long", "hoge"]
|
137
|
+
@opt.parse! arg
|
138
|
+
@opt["long"].should == true
|
139
|
+
arg.should == ["hoge"]
|
140
|
+
end
|
141
|
+
it '「=」でオプション引数指定可能' do
|
142
|
+
arg = ["--long=hoge", "fuga"]
|
143
|
+
@opt.parse! arg
|
144
|
+
@opt["long"].should == "hoge"
|
145
|
+
arg.should == ["fuga"]
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
describe ':argument=>nil & :format=>nil の場合' do
|
150
|
+
before do
|
151
|
+
@opt = OptConfig.new
|
152
|
+
@opt.option "s", :argument=>nil, :format=>nil
|
153
|
+
@opt.option "long", :argument=>nil, :format=>nil
|
154
|
+
end
|
155
|
+
it 'オプション引数を取らない' do
|
156
|
+
proc{@opt.parse ["--long=hoge"]}.should raise_error(OptConfig::UnnecessaryArgument, 'option argument is unnecessary: long')
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
describe ':argument=>nil & :format=>false の場合' do
|
161
|
+
before do
|
162
|
+
@opt = OptConfig.new
|
163
|
+
@opt.option "s", :argument=>nil, :format=>false
|
164
|
+
@opt.option "long", :argument=>nil, :format=>false
|
165
|
+
end
|
166
|
+
it 'オプション引数を取らない' do
|
167
|
+
proc{@opt.parse ["--long=hoge"]}.should raise_error(OptConfig::UnnecessaryArgument, 'option argument is unnecessary: long')
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
describe ':argument=>nil & :format=>true の場合' do
|
172
|
+
before do
|
173
|
+
@opt = OptConfig.new
|
174
|
+
@opt.option "s", :argument=>nil, :format=>true
|
175
|
+
@opt.option "long", :argument=>nil, :format=>true
|
176
|
+
end
|
177
|
+
it 'オプション引数を取る' do
|
178
|
+
@opt.parse ["--long=hoge"]
|
179
|
+
@opt["long"].should == "hoge"
|
180
|
+
proc{@opt.parse ["--long"]}.should raise_error(OptConfig::ArgumentRequired, 'argument required: long')
|
181
|
+
@opt.parse ["-shoge"]
|
182
|
+
@opt["s"].should == "hoge"
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
describe '同じオプションに短い名前と長い名前の2つを設定した場合' do
|
187
|
+
before do
|
188
|
+
@opt = OptConfig.new
|
189
|
+
@opt.option "s", "long"
|
190
|
+
end
|
191
|
+
it 'どちらのオプション名も有効' do
|
192
|
+
@opt.parse(["-s"])
|
193
|
+
@opt["s"].should == true
|
194
|
+
@opt["long"].should == true
|
195
|
+
@opt.parse(["--long"])
|
196
|
+
@opt["s"].should == true
|
197
|
+
@opt["long"].should == true
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
describe '同じオプションに長い名前2つを設定した場合' do
|
202
|
+
before do
|
203
|
+
@opt = OptConfig.new
|
204
|
+
@opt.option "long1", "long2"
|
205
|
+
end
|
206
|
+
it 'どちらのオプション名も有効' do
|
207
|
+
@opt.parse(["--long1"])
|
208
|
+
@opt["long1"].should == true
|
209
|
+
@opt["long2"].should == true
|
210
|
+
@opt.parse(["--long2"])
|
211
|
+
@opt["long1"].should == true
|
212
|
+
@opt["long2"].should == true
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
describe '不正なオプション名を設定した場合' do
|
217
|
+
it 'RuntimeError が発生する' do
|
218
|
+
opt = OptConfig.new
|
219
|
+
proc{opt.option "-abc"}.should raise_error(RuntimeError, 'invalid option name: "-abc"')
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
describe ':format=>Integer を指定した場合' do
|
224
|
+
before do
|
225
|
+
@opt = OptConfig.new
|
226
|
+
@opt.option "s", :format=>Integer
|
227
|
+
end
|
228
|
+
it '数字の引数は正当' do
|
229
|
+
@opt.parse(["-s123"])
|
230
|
+
@opt["s"].should == 123
|
231
|
+
end
|
232
|
+
it '文字列引数はエラー' do
|
233
|
+
proc{@opt.parse(["-sabc"])}.should raise_error(OptConfig::InvalidArgument, 'invalid argument for option `s\': not integer: abc')
|
234
|
+
end
|
235
|
+
it '引数なしはエラー' do
|
236
|
+
proc{@opt.parse(["-s"])}.should raise_error(OptConfig::ArgumentRequired, 'argument required: s')
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
describe ':format=>:boolean を指定した場合' do
|
241
|
+
before do
|
242
|
+
@opt = OptConfig.new
|
243
|
+
@opt.option "s", :format=>:boolean
|
244
|
+
end
|
245
|
+
it '1, true, enable, yes, y, on が true になる' do
|
246
|
+
@opt.parse(["-s","1"])
|
247
|
+
@opt["s"].should == true
|
248
|
+
@opt.parse(["-s","true"])
|
249
|
+
@opt["s"].should == true
|
250
|
+
@opt.parse(["-s","enable"])
|
251
|
+
@opt["s"].should == true
|
252
|
+
@opt.parse(["-s","yes"])
|
253
|
+
@opt["s"].should == true
|
254
|
+
@opt.parse(["-s","y"])
|
255
|
+
@opt["s"].should == true
|
256
|
+
@opt.parse(["-s","on"])
|
257
|
+
@opt["s"].should == true
|
258
|
+
end
|
259
|
+
it '0, false, disable, no, n, off が false になる' do
|
260
|
+
@opt.parse(["-s","0"])
|
261
|
+
@opt["s"].should == false
|
262
|
+
@opt.parse(["-s","false"])
|
263
|
+
@opt["s"].should == false
|
264
|
+
@opt.parse(["-s","disable"])
|
265
|
+
@opt["s"].should == false
|
266
|
+
@opt.parse(["-s","no"])
|
267
|
+
@opt["s"].should == false
|
268
|
+
@opt.parse(["-s","n"])
|
269
|
+
@opt["s"].should == false
|
270
|
+
@opt.parse(["-s","off"])
|
271
|
+
@opt["s"].should == false
|
272
|
+
end
|
273
|
+
it '不正な値で InvalidArgument 例外になる' do
|
274
|
+
proc{@opt.parse(["-s", "x"])}.should raise_error(OptConfig::InvalidArgument, 'invalid boolean value: s')
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
describe ':format=>:boolean & :argument=>:optional の場合' do
|
279
|
+
before do
|
280
|
+
@opt = OptConfig.new
|
281
|
+
@opt.option "s", "long", :format=>:boolean, :argument=>:optional
|
282
|
+
end
|
283
|
+
it 'オプション引数なしで true になる' do
|
284
|
+
@opt.parse(["--long"])
|
285
|
+
@opt["long"].should == true
|
286
|
+
@opt.parse(["-s"])
|
287
|
+
@opt["long"].should == true
|
288
|
+
end
|
289
|
+
it '"--no-" prefix で false になる' do
|
290
|
+
@opt.parse(["--no-long"])
|
291
|
+
@opt["long"].should == false
|
292
|
+
end
|
293
|
+
it '1文字のオプションには "--no-" prefix はつけられない' do
|
294
|
+
proc{@opt.parse(["--no-s"])}.should raise_error(OptConfig::UnknownOption)
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
describe ':format=>:boolean & :argument=>false の場合' do
|
299
|
+
before do
|
300
|
+
@opt = OptConfig.new
|
301
|
+
@opt.option "s", "long", :format=>:boolean, :argument=>false
|
302
|
+
end
|
303
|
+
it 'オプション引数なしで true になる' do
|
304
|
+
@opt.parse(["--long"])
|
305
|
+
@opt["long"].should == true
|
306
|
+
@opt.parse(["-s"])
|
307
|
+
@opt["long"].should == true
|
308
|
+
end
|
309
|
+
it '"--no-" prefix で false になる' do
|
310
|
+
@opt.parse(["--no-long"])
|
311
|
+
@opt["long"].should == false
|
312
|
+
end
|
313
|
+
it '1文字のオプションには "--no-" prefix はつけられない' do
|
314
|
+
proc{@opt.parse(["--no-s"])}.should raise_error(OptConfig::UnknownOption)
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
describe ':format=>:boolean & argument=>true の場合' do
|
319
|
+
before do
|
320
|
+
@opt = OptConfig.new
|
321
|
+
@opt.option "s", "long", :format=>:boolean, :argument=>true
|
322
|
+
end
|
323
|
+
it '"--no-long=true" で false になる' do
|
324
|
+
@opt.parse(["--no-long=true"])
|
325
|
+
@opt["long"].should == false
|
326
|
+
@opt.parse(["--no-long", "true"])
|
327
|
+
@opt["long"].should == false
|
328
|
+
end
|
329
|
+
it '"--no-long=false" で true になる' do
|
330
|
+
@opt.parse(["--no-long=false"])
|
331
|
+
@opt["long"].should == true
|
332
|
+
@opt.parse(["--no-long", "false"])
|
333
|
+
@opt["long"].should == true
|
334
|
+
end
|
335
|
+
it '1文字のオプションには "--no-" prefix はつけられない' do
|
336
|
+
proc{@opt.parse(["--no-s"])}.should raise_error(OptConfig::UnknownOption, "unknown option: no-s")
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
describe ':default を設定した場合' do
|
341
|
+
before do
|
342
|
+
@opt = OptConfig.new
|
343
|
+
@opt.option "s", :format=>true, :default=>"abc"
|
344
|
+
end
|
345
|
+
it 'オプションを指定すると指定した値になる' do
|
346
|
+
@opt.parse(["-s123"])
|
347
|
+
@opt["s"].should == "123"
|
348
|
+
end
|
349
|
+
it 'オプションを指定しないとデフォルト値になる' do
|
350
|
+
@opt.parse()
|
351
|
+
@opt["s"].should == "abc"
|
352
|
+
end
|
353
|
+
end
|
354
|
+
|
355
|
+
describe ':default 値が指定されて、:format が文字列を返さない場合' do
|
356
|
+
before do
|
357
|
+
@opt = OptConfig.new
|
358
|
+
@hostport = proc do |s|
|
359
|
+
h, p = s.split ":", 2
|
360
|
+
h = StringValidator.validate /\A[a-z0-9.-]+\z/, h.to_s
|
361
|
+
p = StringValidator.validate 1..65535, p.to_s
|
362
|
+
[h, p]
|
363
|
+
end
|
364
|
+
end
|
365
|
+
it 'デフォルト値もパースされる' do
|
366
|
+
@opt.option "s", :format=>@hostport, :default=>"localhost:123"
|
367
|
+
@opt.parse
|
368
|
+
@opt["s"].should == ["localhost", 123]
|
369
|
+
end
|
370
|
+
it 'usage の %s は文字列のまま' do
|
371
|
+
@opt.option "s", :format=>@hostport, :default=>"localhost:123", :description=>"%s"
|
372
|
+
@opt.usage.should == " -s localhost:123\n"
|
373
|
+
@opt.parse(["-s", "hoge:80"])
|
374
|
+
@opt.usage.should == " -s hoge:80\n"
|
375
|
+
@opt["s"].should == ["hoge", 80]
|
376
|
+
end
|
377
|
+
it ':format に合わない :default はそのまま' do
|
378
|
+
@opt.option "s", :format=>@hostport, :default=>"123"
|
379
|
+
@opt.parse
|
380
|
+
@opt["s"].should == "123"
|
381
|
+
end
|
382
|
+
it 'String でない :default もそのまま' do
|
383
|
+
@opt.option "s", :format=>@hostport, :default=>123
|
384
|
+
@opt.parse
|
385
|
+
@opt["s"].should == 123
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
389
|
+
describe '未知のオプションの値を取り出そうとした場合' do
|
390
|
+
it 'UnknownOption 例外になる' do
|
391
|
+
opt = OptConfig.new
|
392
|
+
proc{opt["hoge"]}.should raise_error(OptConfig::UnknownOption, 'unknown option: hoge')
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
396
|
+
describe '長いオプションが途中まで指定された場合' do
|
397
|
+
before do
|
398
|
+
@opt = OptConfig.new
|
399
|
+
@opt.option "longhoge"
|
400
|
+
@opt.option "longfuga"
|
401
|
+
end
|
402
|
+
it '曖昧でなければ補完する' do
|
403
|
+
@opt.parse(["--longh"])
|
404
|
+
@opt["longhoge"].should == true
|
405
|
+
@opt["longfuga"].should == nil
|
406
|
+
end
|
407
|
+
it '曖昧であれば AmbiguousOption 例外になる' do
|
408
|
+
proc{@opt.parse(["--long"])}.should raise_error(OptConfig::AmbiguousOption, 'ambiguous option: long (candidate are longfuga, longhoge)')
|
409
|
+
end
|
410
|
+
it ':completion=>false 指定時は補完対象にならない' do
|
411
|
+
opt = OptConfig.new
|
412
|
+
opt.option "longhoge", :completion=>false
|
413
|
+
opt.option "longfuga"
|
414
|
+
opt.parse(["--long"])
|
415
|
+
opt["longfuga"].should == true
|
416
|
+
end
|
417
|
+
end
|
418
|
+
|
419
|
+
describe '説明がないオプションの #usage' do
|
420
|
+
it '出力されない' do
|
421
|
+
opt = OptConfig.new
|
422
|
+
opt.option "x"
|
423
|
+
opt.usage.should == ""
|
424
|
+
end
|
425
|
+
end
|
426
|
+
|
427
|
+
describe '説明が空文字列のオプションの #usage' do
|
428
|
+
it 'オプション名のみ出力される' do
|
429
|
+
opt = OptConfig.new
|
430
|
+
opt.option "x", :description=>""
|
431
|
+
opt.usage.should == " -x\n"
|
432
|
+
end
|
433
|
+
end
|
434
|
+
|
435
|
+
describe '短いオプションの #usage' do
|
436
|
+
it '出力される' do
|
437
|
+
opt = OptConfig.new
|
438
|
+
opt.option "x", :description=>"x option description"
|
439
|
+
opt.usage.should == <<EOS
|
440
|
+
-x x option description
|
441
|
+
EOS
|
442
|
+
end
|
443
|
+
end
|
444
|
+
|
445
|
+
describe '長いオプションの #usage' do
|
446
|
+
it '出力される' do
|
447
|
+
opt = OptConfig.new
|
448
|
+
opt.option "long", :description=>"long option description"
|
449
|
+
opt.usage.should == <<EOS
|
450
|
+
--long long option description
|
451
|
+
EOS
|
452
|
+
end
|
453
|
+
end
|
454
|
+
|
455
|
+
describe '=付きの長いオプションの #usage' do
|
456
|
+
it '出力される' do
|
457
|
+
opt = OptConfig.new
|
458
|
+
opt.option "long=hoge", :description=>"long option description"
|
459
|
+
opt.usage.should == <<EOS
|
460
|
+
--long=hoge long option description
|
461
|
+
EOS
|
462
|
+
end
|
463
|
+
end
|
464
|
+
|
465
|
+
describe '短いオプションと長いオプションの混在 #usage' do
|
466
|
+
it '出力される' do
|
467
|
+
opt = OptConfig.new
|
468
|
+
opt.option "x", :description=>"x option description"
|
469
|
+
opt.option "long", :description=>"long option description"
|
470
|
+
opt.usage.should == <<EOS
|
471
|
+
-x x option description
|
472
|
+
--long long option description
|
473
|
+
EOS
|
474
|
+
end
|
475
|
+
end
|
476
|
+
|
477
|
+
describe '短い名前と長い名前を持つオプションの #usage' do
|
478
|
+
it '同じ行に出力される' do
|
479
|
+
opt = OptConfig.new
|
480
|
+
opt.option "x", "long", :description=>"option description"
|
481
|
+
opt.usage.should == <<EOS
|
482
|
+
-x, --long option description
|
483
|
+
EOS
|
484
|
+
end
|
485
|
+
end
|
486
|
+
|
487
|
+
describe '説明が複数行のオプションの #usage' do
|
488
|
+
it '正しくインデントされる' do
|
489
|
+
opt = OptConfig.new
|
490
|
+
opt.option "long", :description=>"long option\nhogehoge\nfugafuga"
|
491
|
+
opt.usage.should == <<EOS
|
492
|
+
--long long option
|
493
|
+
hogehoge
|
494
|
+
fugafuga
|
495
|
+
EOS
|
496
|
+
end
|
497
|
+
end
|
498
|
+
|
499
|
+
describe 'オプション名が長い場合の #usage' do
|
500
|
+
it '説明が次の行に送られる' do
|
501
|
+
opt = OptConfig.new
|
502
|
+
opt.option "x"
|
503
|
+
opt.option "s", "longlonglonglonglonglong", :description=>"option description"
|
504
|
+
opt.usage.should == <<EOS
|
505
|
+
-s, --longlonglonglonglonglong
|
506
|
+
option description
|
507
|
+
EOS
|
508
|
+
end
|
509
|
+
end
|
510
|
+
|
511
|
+
describe 'オプション説明中に %s があった場合' do
|
512
|
+
before do
|
513
|
+
@opt = OptConfig.new
|
514
|
+
@opt.option "s", :format=>true, :default=>"123", :description=>"short option (%s)"
|
515
|
+
end
|
516
|
+
it '#usage で %s がデフォルト値に置換される' do
|
517
|
+
@opt.usage.should == " -s short option (123)\n"
|
518
|
+
end
|
519
|
+
it 'parse 後は、#usage でオプション値に置換される' do
|
520
|
+
@opt.parse ["-s", "abc"]
|
521
|
+
@opt.usage.should == " -s short option (abc)\n"
|
522
|
+
end
|
523
|
+
end
|
524
|
+
|
525
|
+
describe 'オプションじゃない引数の後にオプションが書かれた場合' do
|
526
|
+
before do
|
527
|
+
@opt = OptConfig.new
|
528
|
+
@opt.option "a"
|
529
|
+
end
|
530
|
+
it 'オプションとみなされる' do
|
531
|
+
arg = ["arg", "-a"]
|
532
|
+
@opt.parse! arg
|
533
|
+
arg.should == ["arg"]
|
534
|
+
@opt["a"].should == true
|
535
|
+
end
|
536
|
+
it '-- の後はオプションではない' do
|
537
|
+
arg = ["arg", "--", "-a"]
|
538
|
+
@opt.parse! arg
|
539
|
+
arg.should == ["arg", "-a"]
|
540
|
+
@opt["a"].should == nil
|
541
|
+
end
|
542
|
+
it ':stop_at_non_option_argument=>true の場合は通常の引数とみなす' do
|
543
|
+
opt = OptConfig.new :stop_at_non_option_argument=>true
|
544
|
+
opt.option "a"
|
545
|
+
arg = ["arg", "-a"]
|
546
|
+
opt.parse! arg
|
547
|
+
arg.should == ["arg", "-a"]
|
548
|
+
opt["a"].should == nil
|
549
|
+
end
|
550
|
+
end
|
551
|
+
|
552
|
+
describe OptConfig, '#parse の戻り値' do
|
553
|
+
before do
|
554
|
+
@opt = OptConfig.new
|
555
|
+
@opt.option "a"
|
556
|
+
@opt.option "b", :format=>true
|
557
|
+
end
|
558
|
+
it 'オプションを除いた引数が返る' do
|
559
|
+
@opt.parse(["-a", "arg"]).should == ["arg"]
|
560
|
+
@opt.parse(["a", "-a", "b"]).should == ["a", "b"]
|
561
|
+
@opt.parse(["-abc", "def"]).should == ["def"]
|
562
|
+
@opt.parse(["-a", "-b", "hoge", "fuga"]).should == ["fuga"]
|
563
|
+
end
|
564
|
+
it '-- を含まない' do
|
565
|
+
@opt.parse(["--", "-a", "arg"]).should == ["-a", "arg"]
|
566
|
+
end
|
567
|
+
end
|
568
|
+
|
569
|
+
describe 'オプションをファイルで指定した場合' do
|
570
|
+
before do
|
571
|
+
@opt = OptConfig.new
|
572
|
+
@opt.option "s", "long", :argument=>true
|
573
|
+
@opt.option "no-arg", :argument=>false
|
574
|
+
end
|
575
|
+
it 'オプションがファイルから読み込まれる' do
|
576
|
+
tmpf = Tempfile.new "optconfig"
|
577
|
+
tmpf.puts <<EOS
|
578
|
+
# コメント
|
579
|
+
long = hoge
|
580
|
+
EOS
|
581
|
+
tmpf.close
|
582
|
+
@opt.file = tmpf.path
|
583
|
+
@opt.parse
|
584
|
+
@opt["long"].should == "hoge"
|
585
|
+
end
|
586
|
+
it '長いオプション名だけ有効' do
|
587
|
+
tmpf = Tempfile.new "optconfig"
|
588
|
+
tmpf.puts <<EOS
|
589
|
+
# コメント
|
590
|
+
s = hoge
|
591
|
+
EOS
|
592
|
+
tmpf.close
|
593
|
+
@opt.file = tmpf.path
|
594
|
+
@opt.parse
|
595
|
+
@opt["long"].should == nil
|
596
|
+
end
|
597
|
+
it 'オプション名の補完なし' do
|
598
|
+
tmpf = Tempfile.new "optconfig"
|
599
|
+
tmpf.puts <<EOS
|
600
|
+
# コメント
|
601
|
+
lo = hoge
|
602
|
+
EOS
|
603
|
+
tmpf.close
|
604
|
+
@opt.file = tmpf.path
|
605
|
+
@opt.parse
|
606
|
+
@opt["long"].should == nil
|
607
|
+
end
|
608
|
+
it '引数を取らないオプションもOK' do
|
609
|
+
tmpf = Tempfile.new "optconfig"
|
610
|
+
tmpf.puts <<EOS
|
611
|
+
# コメント
|
612
|
+
no-arg
|
613
|
+
EOS
|
614
|
+
tmpf.close
|
615
|
+
@opt.file = tmpf.path
|
616
|
+
@opt.parse
|
617
|
+
@opt["no-arg"].should == true
|
618
|
+
end
|
619
|
+
end
|
620
|
+
|
621
|
+
describe 'section を指定' do
|
622
|
+
before do
|
623
|
+
@opt = OptConfig.new
|
624
|
+
@opt.option "s", "long", :argument=>true
|
625
|
+
@opt.option "a", "long2", :argument=>true
|
626
|
+
end
|
627
|
+
it '指定したIDのセクションのみ読み込まれる' do
|
628
|
+
tmpf = Tempfile.new "optconfig"
|
629
|
+
tmpf.puts <<EOS
|
630
|
+
[x]
|
631
|
+
long = hoge
|
632
|
+
[y]
|
633
|
+
long2 = fuga
|
634
|
+
EOS
|
635
|
+
tmpf.close
|
636
|
+
@opt.file = tmpf.path
|
637
|
+
@opt.section = ["y"]
|
638
|
+
@opt.parse
|
639
|
+
@opt["long"].should == nil
|
640
|
+
@opt["long2"].should == "fuga"
|
641
|
+
end
|
642
|
+
end
|
643
|
+
|
644
|
+
describe 'オプション名が --long=value 形式の場合' do
|
645
|
+
it '= の前までをオプション名とみなし、オプション引数ありとみなす' do
|
646
|
+
opt = OptConfig.new
|
647
|
+
opt.option "long=value"
|
648
|
+
opt.instance_variable_get(:@options)["long"].argument.should == true
|
649
|
+
end
|
650
|
+
end
|
651
|
+
|
652
|
+
describe 'オプション名が --long[=value] 形式の場合' do
|
653
|
+
it '= の前までをオプション名とみなし、オプション引数が省略可能とみなす' do
|
654
|
+
opt = OptConfig.new
|
655
|
+
opt.option "long[=value]"
|
656
|
+
opt.instance_variable_get(:@options)["long"].argument.should == :optional
|
657
|
+
end
|
658
|
+
end
|
659
|
+
|
660
|
+
describe 'OptConfig#parse!' do
|
661
|
+
it '引数の配列が書き換わる' do
|
662
|
+
@opt = OptConfig.new
|
663
|
+
@opt.option "s"
|
664
|
+
a = ["-s", "a"]
|
665
|
+
@opt.parse!(a)
|
666
|
+
a.should == ["a"]
|
667
|
+
end
|
668
|
+
end
|
669
|
+
|
670
|
+
describe 'OptConfig#parse' do
|
671
|
+
it '引数の配列が書き換わらない' do
|
672
|
+
@opt = OptConfig.new
|
673
|
+
@opt.option "s"
|
674
|
+
a = ["-s", "a"]
|
675
|
+
@opt.parse(a)
|
676
|
+
a.should == ["-s", "a"]
|
677
|
+
end
|
678
|
+
end
|
679
|
+
|
680
|
+
describe 'OptConfig#ignore_unknown_file_option が true の場合' do
|
681
|
+
it 'ファイル中に未知のオプションがあっても無視される' do
|
682
|
+
@opt = OptConfig.new
|
683
|
+
@opt.ignore_unknown_file_option = true
|
684
|
+
@opt.option "s", "long", :argument=>true
|
685
|
+
tmpf = Tempfile.new "optconfig"
|
686
|
+
tmpf.puts <<EOS
|
687
|
+
long = hoge
|
688
|
+
long2 = fuga
|
689
|
+
EOS
|
690
|
+
tmpf.close
|
691
|
+
@opt.file = tmpf.path
|
692
|
+
@opt.parse
|
693
|
+
@opt["long"].should == "hoge"
|
694
|
+
end
|
695
|
+
end
|
696
|
+
|
697
|
+
describe 'OptConfig#ignore_unknown_file_option が false の場合' do
|
698
|
+
it 'ファイル中に未知のオプションがあれば OptConfig::UnknownOption 例外になる' do
|
699
|
+
@opt = OptConfig.new
|
700
|
+
@opt.ignore_unknown_file_option = false
|
701
|
+
@opt.option "s", "long", :argument=>true
|
702
|
+
tmpf = Tempfile.new "optconfig"
|
703
|
+
tmpf.puts <<EOS
|
704
|
+
long = hoge
|
705
|
+
long2 = fuga
|
706
|
+
EOS
|
707
|
+
tmpf.close
|
708
|
+
@opt.file = tmpf.path
|
709
|
+
proc{@opt.parse}.should raise_error(OptConfig::UnknownOption, "unknown option: long2")
|
710
|
+
end
|
711
|
+
it '定義済みのオプションでも :in_config=>false であれば OptConfig::UnknownOption 例外になる' do
|
712
|
+
@opt = OptConfig.new
|
713
|
+
@opt.ignore_unknown_file_option = false
|
714
|
+
@opt.option "s", "long", :argument=>true, :in_config=>false
|
715
|
+
tmpf = Tempfile.new "optconfig"
|
716
|
+
tmpf.puts <<EOS
|
717
|
+
long = hoge
|
718
|
+
EOS
|
719
|
+
tmpf.close
|
720
|
+
@opt.file = tmpf.path
|
721
|
+
proc{@opt.parse}.should raise_error(OptConfig::UnknownOption, "unknown option: long")
|
722
|
+
end
|
723
|
+
end
|
724
|
+
|
725
|
+
describe 'オプションの二重定義' do
|
726
|
+
it 'RuntimeError になる' do
|
727
|
+
opt = OptConfig.new
|
728
|
+
proc{opt.option "s"; opt.option "s"}.should raise_error(RuntimeError, 'option s is already defined')
|
729
|
+
end
|
730
|
+
end
|
731
|
+
|
732
|
+
describe ':multiple 指定なし' do
|
733
|
+
it '同じオプションの複数指定時、最後のオプションが有効' do
|
734
|
+
opt = OptConfig.new
|
735
|
+
opt.option "s", :format=>true
|
736
|
+
opt.parse(["-s","123","-s","abc"])
|
737
|
+
opt["s"].should == "abc"
|
738
|
+
end
|
739
|
+
end
|
740
|
+
|
741
|
+
describe ':multiple=>:last を指定' do
|
742
|
+
it '同じオプションの複数指定時、最後のオプションが有効' do
|
743
|
+
opt = OptConfig.new
|
744
|
+
opt.option "s", :format=>true, :multiple=>:last
|
745
|
+
opt.parse(["-s","123","-s","abc"])
|
746
|
+
opt["s"].should == "abc"
|
747
|
+
end
|
748
|
+
end
|
749
|
+
|
750
|
+
describe ':multiple=>false を指定' do
|
751
|
+
it '同じオプションの複数指定でエラー' do
|
752
|
+
opt = OptConfig.new
|
753
|
+
opt.option "s", :format=>true, :multiple=>false
|
754
|
+
proc{opt.parse(["-s","123","-s","abc"])}.should raise_error(OptConfig::DuplicatedOption, "duplicated option: s")
|
755
|
+
end
|
756
|
+
it '異なる名前でも同じオプションであれば複数指定でエラー' do
|
757
|
+
opt = OptConfig.new
|
758
|
+
opt.option "s", "long", :format=>true, :multiple=>false
|
759
|
+
proc{opt.parse(["-s","123","--long","abc"])}.should raise_error(OptConfig::DuplicatedOption, "duplicated option: long")
|
760
|
+
end
|
761
|
+
end
|
762
|
+
|
763
|
+
describe ':multiple=>true を指定' do
|
764
|
+
it '同じオプションの複数指定で配列が返る' do
|
765
|
+
opt = OptConfig.new
|
766
|
+
opt.option "s", :format=>true, :multiple=>true
|
767
|
+
opt.parse(["-s","123","-s","abc"])
|
768
|
+
opt["s"].should == ["123","abc"]
|
769
|
+
end
|
770
|
+
end
|
771
|
+
|
772
|
+
describe ':argument=>true を指定' do
|
773
|
+
before do
|
774
|
+
@opt = OptConfig.new
|
775
|
+
@opt.option "s", "long", :argument=>true
|
776
|
+
end
|
777
|
+
it '長いオプション名: 「=」があれば、それ以降がオプション引数' do
|
778
|
+
@opt.parse(["--long=hoge"])
|
779
|
+
@opt["long"].should == "hoge"
|
780
|
+
end
|
781
|
+
it '短いオプション名: オプション名以降に文字列があれば、それがオプション引数' do
|
782
|
+
@opt.parse(["-shoge"])
|
783
|
+
@opt["s"].should == "hoge"
|
784
|
+
end
|
785
|
+
it '次の引数が「-」で始まっていても、オプション引数' do
|
786
|
+
@opt.parse(["--long", "--hoge"])
|
787
|
+
@opt["long"].should == "--hoge"
|
788
|
+
@opt.parse(["-s", "--hoge"])
|
789
|
+
@opt["s"].should == "--hoge"
|
790
|
+
end
|
791
|
+
end
|
792
|
+
|
793
|
+
describe ':argument=>false を指定' do
|
794
|
+
before do
|
795
|
+
@opt = OptConfig.new
|
796
|
+
@opt.option "s", "long", :argument=>false
|
797
|
+
end
|
798
|
+
it 'オプション引数が指定されたらエラー' do
|
799
|
+
proc{@opt.parse(["--long=hoge"])}.should raise_error(OptConfig::UnnecessaryArgument, "option argument is unnecessary: long")
|
800
|
+
end
|
801
|
+
it 'オプションの次の引数はオプション引数でない' do
|
802
|
+
arg = ["-s", "hoge"]
|
803
|
+
@opt.parse!(arg)
|
804
|
+
arg.should == ["hoge"]
|
805
|
+
arg = ["--long", "hoge"]
|
806
|
+
@opt.parse!(arg)
|
807
|
+
arg.should == ["hoge"]
|
808
|
+
end
|
809
|
+
end
|
810
|
+
|
811
|
+
describe ':argument=>:optional を指定' do
|
812
|
+
before do
|
813
|
+
@opt = OptConfig.new
|
814
|
+
@opt.option "s", "long", :format=>true, :argument=>:optional
|
815
|
+
@opt.option "hoge"
|
816
|
+
end
|
817
|
+
it '長いオプション名: 「=」があれば、それ以降がオプション引数' do
|
818
|
+
@opt.parse(["--long=hoge"])
|
819
|
+
@opt["long"].should == "hoge"
|
820
|
+
end
|
821
|
+
it '長いオプション名: 「=」がなければ、オプション引数なし' do
|
822
|
+
@opt.parse(["--long", "hoge"])
|
823
|
+
@opt["long"].should == true
|
824
|
+
end
|
825
|
+
it '短いオプション名: オプション名以降に文字列があれば、それがオプション引数' do
|
826
|
+
@opt.parse(["-shoge"])
|
827
|
+
@opt["s"].should == "hoge"
|
828
|
+
end
|
829
|
+
it '短いオプション名: オプション名以降に文字列がなければ、オプション引数なし' do
|
830
|
+
@opt.parse(["-s", "hoge"])
|
831
|
+
@opt["s"].should == true
|
832
|
+
end
|
833
|
+
end
|
834
|
+
|
835
|
+
describe ':underscore_is_hyphen=>true を指定' do
|
836
|
+
before do
|
837
|
+
@opt = OptConfig.new
|
838
|
+
@opt.option "long-opt", :format=>true, :underscore_is_hyphen=>true
|
839
|
+
end
|
840
|
+
it '--long-opt が --long_opt でも有効' do
|
841
|
+
@opt.parse(["--long_opt=hoge"])
|
842
|
+
@opt["long-opt"].should == "hoge"
|
843
|
+
end
|
844
|
+
it 'conf ファイル中の long_opt が有効' do
|
845
|
+
tmpf = Tempfile.new "optconfig"
|
846
|
+
tmpf.puts <<EOS
|
847
|
+
long_opt = hoge
|
848
|
+
EOS
|
849
|
+
tmpf.close
|
850
|
+
@opt.file = tmpf.path
|
851
|
+
@opt.parse
|
852
|
+
@opt["long-opt"].should == "hoge"
|
853
|
+
end
|
854
|
+
end
|
855
|
+
|
856
|
+
describe ':underscore_is_hyphen=>true で "--no-" prefix の場合' do
|
857
|
+
before do
|
858
|
+
@opt = OptConfig.new
|
859
|
+
@opt.option "long-opt", :format=>:boolean, :argument=>false, :underscore_is_hyphen=>true
|
860
|
+
end
|
861
|
+
it '--long_opt 指定で true' do
|
862
|
+
@opt.parse(["--long_opt"])
|
863
|
+
@opt["long-opt"].should == true
|
864
|
+
end
|
865
|
+
it '--no_long_opt 指定で false' do
|
866
|
+
@opt.parse(["--no_long_opt"])
|
867
|
+
@opt["long-opt"].should == false
|
868
|
+
end
|
869
|
+
end
|
870
|
+
|
871
|
+
describe ':in_config=>false を指定' do
|
872
|
+
before do
|
873
|
+
@opt = OptConfig.new
|
874
|
+
@opt.option "long", :format=>"hoge", :in_config=>false
|
875
|
+
end
|
876
|
+
it '引数に書けば有効' do
|
877
|
+
@opt.parse(["--long", "hoge"])
|
878
|
+
@opt["long"].should == "hoge"
|
879
|
+
end
|
880
|
+
it '設定ファイルに書いても無効' do
|
881
|
+
tmpf = Tempfile.new "optconfig"
|
882
|
+
tmpf.puts <<EOS
|
883
|
+
long = hoge
|
884
|
+
EOS
|
885
|
+
tmpf.close
|
886
|
+
@opt.file = tmpf.path
|
887
|
+
@opt.parse
|
888
|
+
@opt["long"].should be_nil
|
889
|
+
end
|
890
|
+
it '設定ファイル内で形式違反の値が指定されていても無視' do
|
891
|
+
tmpf = Tempfile.new "optconfig"
|
892
|
+
tmpf.puts <<EOS
|
893
|
+
long = fuga
|
894
|
+
EOS
|
895
|
+
tmpf.close
|
896
|
+
@opt.file = tmpf.path
|
897
|
+
@opt.parse
|
898
|
+
@opt["long"].should be_nil
|
899
|
+
end
|
900
|
+
end
|
901
|
+
|
902
|
+
describe 'OptConfig.new でデフォルト属性を指定' do
|
903
|
+
it 'オプションの属性に適用される' do
|
904
|
+
opt = OptConfig.new :argument=>:optional, :completion=>false
|
905
|
+
opt.option "s"
|
906
|
+
opt.instance_variable_get(:@options)["s"].argument.should == :optional
|
907
|
+
opt.instance_variable_get(:@options)["s"].completion.should == false
|
908
|
+
end
|
909
|
+
end
|
910
|
+
|
911
|
+
describe ':proc' do
|
912
|
+
before do
|
913
|
+
@opt = OptConfig.new
|
914
|
+
@cnt = 0
|
915
|
+
block = proc do |name, opt, arg|
|
916
|
+
@cnt += 1
|
917
|
+
name.should == "p"
|
918
|
+
arg.should == "hoge"
|
919
|
+
"fuga"
|
920
|
+
end
|
921
|
+
@opt.option "p", "proc", :format=>"hoge", :proc=>block
|
922
|
+
end
|
923
|
+
it 'オプション毎に実行される' do
|
924
|
+
@opt.parse(["-p", "hoge", "-p", "hoge"])
|
925
|
+
@cnt.should == 2
|
926
|
+
end
|
927
|
+
it 'ブロックの結果が OptConfig#[] の戻り値になる' do
|
928
|
+
@opt.parse(["-p", "hoge"])
|
929
|
+
@opt["proc"].should == "fuga"
|
930
|
+
end
|
931
|
+
it 'オプション引数の正当性確認後に実行される' do
|
932
|
+
proc{@opt.parse(["-p", "fuga"])}.should raise_error(OptConfig::InvalidArgument, "invalid argument for option `p': invalid value: fuga")
|
933
|
+
@cnt.should == 0
|
934
|
+
end
|
935
|
+
end
|
936
|
+
|
937
|
+
describe ':pre_proc' do
|
938
|
+
before do
|
939
|
+
@opt = OptConfig.new
|
940
|
+
@cnt = 0
|
941
|
+
block = proc do |name, opt, arg|
|
942
|
+
@cnt += 1
|
943
|
+
name.should == "p"
|
944
|
+
arg == "fuga" ? "hoge" : arg
|
945
|
+
end
|
946
|
+
@opt.option "p", "proc", :format=>"hoge", :pre_proc=>block
|
947
|
+
end
|
948
|
+
it 'オプション毎に実行される' do
|
949
|
+
@opt.parse(["-p", "hoge", "-p", "hoge"])
|
950
|
+
@cnt.should == 2
|
951
|
+
end
|
952
|
+
it 'ブロックの結果をオプション引数とする' do
|
953
|
+
@opt.parse(["-p", "fuga"])
|
954
|
+
@opt["p"].should == "hoge"
|
955
|
+
end
|
956
|
+
it 'オプション引数の正当性確認前に実行される' do
|
957
|
+
proc{@opt.parse(["-p", "xxx"])}.should raise_error(OptConfig::InvalidArgument, "invalid argument for option `p': invalid value: xxx")
|
958
|
+
@cnt.should == 1
|
959
|
+
end
|
960
|
+
end
|
961
|
+
|
962
|
+
describe 'options= でオプション設定' do
|
963
|
+
before do
|
964
|
+
@opt = OptConfig.new
|
965
|
+
@opt.options = {
|
966
|
+
"a" => nil,
|
967
|
+
"b" => false,
|
968
|
+
"c" => true,
|
969
|
+
"long" => true,
|
970
|
+
"long2" => [true, "abc"],
|
971
|
+
"long3" => /abc/,
|
972
|
+
["d", "long4"] => true,
|
973
|
+
}
|
974
|
+
end
|
975
|
+
it 'nil の場合は引数なし' do
|
976
|
+
@opt.parse(["-a", "a"]).should == 1
|
977
|
+
@opt["a"].should == true
|
978
|
+
end
|
979
|
+
it 'false の場合は引数なし' do
|
980
|
+
@opt.parse(["-b", "a"]).should == 1
|
981
|
+
@opt["b"].should == true
|
982
|
+
end
|
983
|
+
it 'true の場合は引数あり' do
|
984
|
+
@opt.parse(["-c", "a"]).should == 2
|
985
|
+
@opt["c"].should == "a"
|
986
|
+
end
|
987
|
+
it '長いオプション名も使用可能' do
|
988
|
+
@opt.parse(["--long", "a"]).should == 2
|
989
|
+
@opt["long"].should == "a"
|
990
|
+
end
|
991
|
+
it 'オプションが指定されなくても引数のデフォルト値が有効' do
|
992
|
+
@opt.parse(["a"]).should == 0
|
993
|
+
@opt["long2"].should == "abc"
|
994
|
+
end
|
995
|
+
it '引数の形式を指定可能' do
|
996
|
+
@opt.parse(["--long3", "bcabcab"]).should == 2
|
997
|
+
@opt["long3"].should == "bcabcab"
|
998
|
+
end
|
999
|
+
it '引数の形式に合わなければエラー' do
|
1000
|
+
proc{@opt.parse(["--long3", "hogehoge"])}.should raise_error(OptConfig::InvalidArgument, "invalid argument for option `long3': regexp mismatch: hogehoge")
|
1001
|
+
end
|
1002
|
+
it '同じオプションに短い名前と長い名前を指定可能' do
|
1003
|
+
@opt.parse(["-d", "a"]).should == 2
|
1004
|
+
@opt["long4"].should == "a"
|
1005
|
+
end
|
1006
|
+
end
|
metadata
CHANGED
@@ -1,64 +1,59 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: optconfig
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.4.5
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
|
-
authors:
|
7
|
+
authors:
|
7
8
|
- Tomita Masahiro
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
dependencies:
|
15
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2011-12-07 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
16
15
|
name: stringvalidator
|
16
|
+
requirement: &78858330 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
17
22
|
type: :runtime
|
18
|
-
|
19
|
-
version_requirements:
|
20
|
-
requirements:
|
21
|
-
- - ">="
|
22
|
-
- !ruby/object:Gem::Version
|
23
|
-
version: "0"
|
24
|
-
version:
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *78858330
|
25
25
|
description: OptConfig is a parser of command line option
|
26
26
|
email: tommy@tmtm.org
|
27
27
|
executables: []
|
28
|
-
|
29
28
|
extensions: []
|
30
|
-
|
31
29
|
extra_rdoc_files: []
|
32
|
-
|
33
|
-
files:
|
30
|
+
files:
|
34
31
|
- lib/optconfig.rb
|
35
|
-
|
32
|
+
- spec/optconfig_spec.rb
|
36
33
|
homepage: http://github.com/tmtm/optconfig
|
37
|
-
licenses:
|
38
|
-
|
34
|
+
licenses:
|
35
|
+
- Ruby's
|
39
36
|
post_install_message:
|
40
|
-
rdoc_options:
|
41
|
-
|
42
|
-
require_paths:
|
37
|
+
rdoc_options: []
|
38
|
+
require_paths:
|
43
39
|
- lib
|
44
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
40
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
47
|
+
none: false
|
48
|
+
requirements:
|
49
|
+
- - ! '>='
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '0'
|
56
52
|
requirements: []
|
57
|
-
|
58
|
-
|
59
|
-
rubygems_version: 1.3.4
|
53
|
+
rubyforge_project:
|
54
|
+
rubygems_version: 1.8.11
|
60
55
|
signing_key:
|
61
56
|
specification_version: 3
|
62
57
|
summary: OptConfig is a parser of command line option
|
63
|
-
test_files:
|
64
|
-
|
58
|
+
test_files:
|
59
|
+
- spec/optconfig_spec.rb
|