benry-cmdopt 2.2.0 → 2.4.0
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 +4 -4
- data/CHANGES.md +13 -1
- data/README.md +67 -6
- data/benry-cmdopt.gemspec +1 -1
- data/doc/benry-cmdopt.html +62 -6
- data/doc/css/style.css +2 -2
- data/lib/benry/cmdopt.rb +53 -12
- data/test/cmdopt_test.rb +1 -1526
- data/test/facade_test.rb +197 -0
- data/test/item_test.rb +463 -0
- data/test/parser_test.rb +294 -0
- data/test/run_all.rb +6 -0
- data/test/schema_test.rb +727 -0
- data/test/shared.rb +6 -0
- metadata +12 -2
data/test/cmdopt_test.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
require 'oktest'
|
4
5
|
|
@@ -8,1344 +9,6 @@ require 'benry/cmdopt'
|
|
8
9
|
Oktest.scope do
|
9
10
|
|
10
11
|
|
11
|
-
def new_sample_schema()
|
12
|
-
sc = Benry::CmdOpt::Schema.new
|
13
|
-
sc.add(:help , "-h, --help" , "show help message.")
|
14
|
-
sc.add(:version, "--version" , "print version")
|
15
|
-
sc.add(:file , "-f, --file=<FILE>" , "filename")
|
16
|
-
sc.add(:indent , "-i, --indent[=<WIDTH>]", "enable indent", type: Integer)
|
17
|
-
sc.add(:mode , "-m, --mode=<MODE>" , "mode", enum: ['verbose', 'quiet'])
|
18
|
-
sc.add(:libpath, "-I, --path=<PATH>" , "library path (multiple ok)") do |optdef, key, val|
|
19
|
-
File.directory?(val) or raise "Directory not exist."
|
20
|
-
arr = optdef[key] || []
|
21
|
-
arr << val
|
22
|
-
arr
|
23
|
-
end
|
24
|
-
sc
|
25
|
-
end
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
topic Benry::CmdOpt::Schema do
|
30
|
-
|
31
|
-
|
32
|
-
topic '#parse()' do
|
33
|
-
|
34
|
-
before do
|
35
|
-
@schema = Benry::CmdOpt::Schema.new
|
36
|
-
end
|
37
|
-
|
38
|
-
spec "[!qw0ac] parses command option definition string." do
|
39
|
-
sc = @schema
|
40
|
-
tuple = sc.__send__(:parse_optdef, "-h, --help")
|
41
|
-
ok {tuple} == ['h', 'help', nil, nil]
|
42
|
-
tuple = sc.__send__(:parse_optdef, "-h")
|
43
|
-
ok {tuple} == ['h', nil, nil, nil]
|
44
|
-
tuple = sc.__send__(:parse_optdef, "--help")
|
45
|
-
ok {tuple} == [nil, 'help', nil, nil]
|
46
|
-
end
|
47
|
-
|
48
|
-
spec "[!ae733] parses command option definition which has a required param." do
|
49
|
-
sc = @schema
|
50
|
-
tuple = sc.__send__(:parse_optdef, "-f, --file=<FILE>")
|
51
|
-
ok {tuple} == ['f', 'file', '<FILE>', true]
|
52
|
-
tuple = sc.__send__(:parse_optdef, "-f <FILE>")
|
53
|
-
ok {tuple} == ['f', nil, '<FILE>', true]
|
54
|
-
tuple = sc.__send__(:parse_optdef, "--file=<FILE>")
|
55
|
-
ok {tuple} == [nil, 'file', '<FILE>', true]
|
56
|
-
end
|
57
|
-
|
58
|
-
spec "[!4h05c] parses command option definition which has an optional param." do
|
59
|
-
sc = @schema
|
60
|
-
tuple = sc.__send__(:parse_optdef, "-i, --indent[=<WIDTH>]")
|
61
|
-
ok {tuple} == ['i', 'indent', '<WIDTH>', false]
|
62
|
-
tuple = sc.__send__(:parse_optdef, "-i[<WIDTH>]")
|
63
|
-
ok {tuple} == ['i', nil, '<WIDTH>', false]
|
64
|
-
tuple = sc.__send__(:parse_optdef, "--indent[=<WIDTH>]")
|
65
|
-
ok {tuple} == [nil, 'indent', '<WIDTH>', false]
|
66
|
-
end
|
67
|
-
|
68
|
-
spec "[!b7jo3] raises SchemaError when command option definition is invalid." do
|
69
|
-
sc = @schema
|
70
|
-
pr = proc {
|
71
|
-
tuple = sc.__send__(:parse_optdef, "-i, --indent <WIDTH>")
|
72
|
-
}
|
73
|
-
ok {pr}.raise?(Benry::CmdOpt::SchemaError,
|
74
|
-
"-i, --indent <WIDTH>: Invalid option definition (use '=--indent' instead of ' --indent').")
|
75
|
-
end
|
76
|
-
|
77
|
-
end
|
78
|
-
|
79
|
-
|
80
|
-
topic '#dup()' do
|
81
|
-
|
82
|
-
before do
|
83
|
-
@schema = Benry::CmdOpt::Schema.new
|
84
|
-
@schema.add(:help , "-h" , "print help")
|
85
|
-
end
|
86
|
-
|
87
|
-
spec "[!lxb0o] copies self object." do
|
88
|
-
this = @schema
|
89
|
-
other = @schema.dup()
|
90
|
-
#
|
91
|
-
this_items = this.instance_variable_get(:@items)
|
92
|
-
other_items = other.instance_variable_get(:@items)
|
93
|
-
ok {this_items} != nil
|
94
|
-
ok {other_items} != nil
|
95
|
-
ok {other_items} == this_items
|
96
|
-
ok {other_items.object_id} != this_items.object_id
|
97
|
-
#
|
98
|
-
this.add(:silent, "-s", "silent")
|
99
|
-
other.add(:quiet, "-q", "quiet")
|
100
|
-
ok {this.option_help()} == (" -h : print help\n" +
|
101
|
-
" -s : silent\n")
|
102
|
-
ok {other.option_help()} == (" -h : print help\n" +
|
103
|
-
" -q : quiet\n")
|
104
|
-
end
|
105
|
-
|
106
|
-
end
|
107
|
-
|
108
|
-
|
109
|
-
topic '#copy_from()' do
|
110
|
-
|
111
|
-
before do
|
112
|
-
@schema1 = Benry::CmdOpt::Schema.new
|
113
|
-
@schema1.add(:help, "-h" , "print help")
|
114
|
-
@schema2 = Benry::CmdOpt::Schema.new
|
115
|
-
@schema2.add(:version, "-v" , "print version")
|
116
|
-
@schema2.add(:debug , "-D" , "debug mode")
|
117
|
-
end
|
118
|
-
|
119
|
-
spec "[!6six3] copy schema items from others." do
|
120
|
-
@schema1.copy_from(@schema2)
|
121
|
-
tuples = @schema1.each.collect {|x| [x.key, x.optdef, x.desc] }
|
122
|
-
ok {tuples} == [
|
123
|
-
[:help , "-h", "print help"],
|
124
|
-
[:version, "-v", "print version"],
|
125
|
-
[:debug , "-D", "debug mode"],
|
126
|
-
]
|
127
|
-
end
|
128
|
-
|
129
|
-
spec "[!vt88s] copy schema items except items specified by 'except:' kwarg." do
|
130
|
-
@schema1.copy_from(@schema2, except: [:debug])
|
131
|
-
tuples = @schema1.each.collect {|x| [x.key, x.optdef, x.desc] }
|
132
|
-
ok {tuples} == [
|
133
|
-
[:help, "-h", "print help"],
|
134
|
-
[:version, "-v", "print version"],
|
135
|
-
]
|
136
|
-
end
|
137
|
-
|
138
|
-
end
|
139
|
-
|
140
|
-
|
141
|
-
topic '#add()' do
|
142
|
-
|
143
|
-
before do
|
144
|
-
@schema = Benry::CmdOpt::Schema.new
|
145
|
-
end
|
146
|
-
|
147
|
-
spec "[!7hi2d] takes command option definition string." do
|
148
|
-
sc = @schema
|
149
|
-
sc.add(:indent, "-i, --indent=<WIDTH>", "print help")
|
150
|
-
items = sc.instance_eval { @items }
|
151
|
-
ok {items.length} == 1
|
152
|
-
ok {items[0]}.is_a?(Benry::CmdOpt::SchemaItem)
|
153
|
-
ok {items[0].key} == :indent
|
154
|
-
ok {items[0].short} == 'i'
|
155
|
-
ok {items[0].long} == 'indent'
|
156
|
-
ok {items[0].param} == '<WIDTH>'
|
157
|
-
ok {items[0].required?} == true
|
158
|
-
ok {items[0].type} == nil
|
159
|
-
ok {items[0].rexp} == nil
|
160
|
-
ok {items[0].enum} == nil
|
161
|
-
ok {items[0].callback} == nil
|
162
|
-
end
|
163
|
-
|
164
|
-
spec "[!p9924] option key is omittable only when long option specified." do
|
165
|
-
sc = @schema
|
166
|
-
sc.add(nil, "-m, --max-num=<N>", nil)
|
167
|
-
items = sc.instance_eval { @items }
|
168
|
-
ok {items[0].key} == :max_num
|
169
|
-
end
|
170
|
-
|
171
|
-
spec "[!jtp7z] raises SchemaError when key is nil and no long option." do
|
172
|
-
sc = @schema
|
173
|
-
pr = proc { sc.add(nil, "-i <N>", nil) }
|
174
|
-
msg = "add(nil, \"-i <N>\"): Long option required when option key (1st arg) not specified."
|
175
|
-
ok {pr}.raise?(Benry::CmdOpt::SchemaError, msg)
|
176
|
-
end
|
177
|
-
|
178
|
-
spec "[!rpl98] when long option is 'foo-bar' then key name is ':foo_bar'." do
|
179
|
-
sc = @schema
|
180
|
-
sc.add(nil, "--foo-bar", nil)
|
181
|
-
items = sc.instance_eval { @items }
|
182
|
-
ok {items[0].key} == :foo_bar
|
183
|
-
end
|
184
|
-
|
185
|
-
spec "[!97sn0] raises SchemaError when ',' is missing between short and long options." do
|
186
|
-
sc = @schema
|
187
|
-
pr = proc { sc.add(:exec, '-x --exec=ARG', "exec") }
|
188
|
-
msg = "add(:exec, \"-x --exec=ARG\"): Missing ',' between short option and long options."
|
189
|
-
ok {pr}.raise?(Benry::CmdOpt::SchemaError, msg)
|
190
|
-
end
|
191
|
-
|
192
|
-
spec "[!yht0v] keeps command option definitions." do
|
193
|
-
sc = @schema
|
194
|
-
sc.add(:indent, "-i, --indent[=<WIDTH>]", "indent width",
|
195
|
-
range: (1..2), value: 8, detail: "(description)", tag: :ab,
|
196
|
-
type: Integer, rexp: /\A\d+\z/, enum: [2, 4, 8]) {|v| v.to_i }
|
197
|
-
items = sc.instance_eval { @items }
|
198
|
-
ok {items.length} == 1
|
199
|
-
ok {items[0]}.is_a?(Benry::CmdOpt::SchemaItem)
|
200
|
-
ok {items[0].key} == :indent
|
201
|
-
ok {items[0].short} == 'i'
|
202
|
-
ok {items[0].long} == 'indent'
|
203
|
-
ok {items[0].param} == '<WIDTH>'
|
204
|
-
ok {items[0].required?} == false
|
205
|
-
ok {items[0].type} == Integer
|
206
|
-
ok {items[0].rexp} == /\A\d+\z/
|
207
|
-
ok {items[0].enum} == [2, 4, 8]
|
208
|
-
ok {items[0].range} == (1..2)
|
209
|
-
ok {items[0].detail} == "(description)"
|
210
|
-
ok {items[0].value} == 8
|
211
|
-
ok {items[0].tag} == :ab
|
212
|
-
ok {items[0].callback}.is_a?(Proc)
|
213
|
-
ok {items[0].callback.arity} == 1
|
214
|
-
end
|
215
|
-
|
216
|
-
spec "[!kuhf9] type, rexp, enum, and range are can be passed as positional args as well as keyword args." do
|
217
|
-
sc = @schema
|
218
|
-
sc.add(:key, "--optdef=xx", "desc", Integer, /\A\d+\z/, [2,4,8], (2..8))
|
219
|
-
item = sc.each.first
|
220
|
-
ok {item.type} == Integer
|
221
|
-
ok {item.rexp} == /\A\d+\z/
|
222
|
-
ok {item.enum} == [2,4,8]
|
223
|
-
ok {item.range} == (2..8)
|
224
|
-
end
|
225
|
-
|
226
|
-
spec "[!e3emy] raises error when positional arg is not one of class, regexp, array, nor range." do
|
227
|
-
sc = @schema
|
228
|
-
pr = proc { sc.add(:key, "--optdef=xx", "desc", "value") }
|
229
|
-
ok {pr}.raise?(Benry::CmdOpt::SchemaError,
|
230
|
-
'"value": Expected one of class, regexp, array or range, but got String.')
|
231
|
-
end
|
232
|
-
|
233
|
-
spec "[!rhhji] raises SchemaError when key is not a Symbol." do
|
234
|
-
sc = @schema
|
235
|
-
pr = proc {
|
236
|
-
sc.add("-i, --indent[=<WIDTH>]", "indent width", nil)
|
237
|
-
}
|
238
|
-
ok {pr}.raise?(Benry::CmdOpt::SchemaError,
|
239
|
-
'add("-i, --indent[=<WIDTH>]", "indent width"): The first arg should be a Symbol as an option key.')
|
240
|
-
end
|
241
|
-
|
242
|
-
spec "[!vq6eq] raises SchemaError when help message is missing." do
|
243
|
-
sc = @schema
|
244
|
-
pr = proc {
|
245
|
-
begin
|
246
|
-
sc.add(:indent, "-i, --indent[=<WIDTH>]", type: Array) # Ruby 2
|
247
|
-
rescue ArgumentError
|
248
|
-
sc.add(:indent, "-i, --indent[=<WIDTH>]", {type: Array}) # Ruby 3
|
249
|
-
end
|
250
|
-
}
|
251
|
-
ok {pr}.raise?(Benry::CmdOpt::SchemaError,
|
252
|
-
'add(:indent, "-i, --indent[=<WIDTH>]"): Help message required as 3rd argument.')
|
253
|
-
end
|
254
|
-
|
255
|
-
|
256
|
-
end
|
257
|
-
|
258
|
-
|
259
|
-
topic '#add_item()' do
|
260
|
-
|
261
|
-
spec "[!a693h] adds option item into current schema." do
|
262
|
-
item = Benry::CmdOpt::SchemaItem.new(:quiet, "-q", "quiet", "q", nil, nil, false)
|
263
|
-
sc = Benry::CmdOpt::Schema.new
|
264
|
-
sc.add_item(item)
|
265
|
-
ok {sc.to_s} == <<"END"
|
266
|
-
-q : quiet
|
267
|
-
END
|
268
|
-
end
|
269
|
-
|
270
|
-
end
|
271
|
-
|
272
|
-
topic '#option_help()' do
|
273
|
-
|
274
|
-
before do
|
275
|
-
sc = Benry::CmdOpt::Schema.new
|
276
|
-
sc.add(:help , "-h, --help" , "show help message.")
|
277
|
-
sc.add(:version, " --version" , "print version")
|
278
|
-
sc.add(:file , "-f, --file=<FILE>" , "filename")
|
279
|
-
sc.add(:indent , "-i, --indent[=<WIDTH>]", "enable indent", type: Integer)
|
280
|
-
sc.add(:debug , "-d, --debug" , nil)
|
281
|
-
@schema = sc
|
282
|
-
end
|
283
|
-
|
284
|
-
spec "[!0aq0i] can take integer as width." do
|
285
|
-
helpmsg = @schema.option_help(41)
|
286
|
-
ok {helpmsg} == <<END
|
287
|
-
-h, --help : show help message.
|
288
|
-
--version : print version
|
289
|
-
-f, --file=<FILE> : filename
|
290
|
-
-i, --indent[=<WIDTH>] : enable indent
|
291
|
-
END
|
292
|
-
s = helpmsg.each_line.first.split(':')[0]
|
293
|
-
ok {s.length} == 41+3
|
294
|
-
end
|
295
|
-
|
296
|
-
spec "[!pcsah] can take format string." do
|
297
|
-
helpmsg = @schema.option_help("%-42s: %s")
|
298
|
-
ok {helpmsg} == <<END
|
299
|
-
-h, --help : show help message.
|
300
|
-
--version : print version
|
301
|
-
-f, --file=<FILE> : filename
|
302
|
-
-i, --indent[=<WIDTH>] : enable indent
|
303
|
-
END
|
304
|
-
s = helpmsg.each_line.first.split(':')[0]
|
305
|
-
ok {s.length} == 42+0
|
306
|
-
end
|
307
|
-
|
308
|
-
spec "[!dndpd] detects option width automatically when nothing specified." do
|
309
|
-
helpmsg = @schema.option_help()
|
310
|
-
ok {helpmsg} == <<END
|
311
|
-
-h, --help : show help message.
|
312
|
-
--version : print version
|
313
|
-
-f, --file=<FILE> : filename
|
314
|
-
-i, --indent[=<WIDTH>] : enable indent
|
315
|
-
END
|
316
|
-
s = helpmsg.each_line.to_a.last.split(':')[0]
|
317
|
-
ok {s.length} == 25
|
318
|
-
end
|
319
|
-
|
320
|
-
spec "[!v7z4x] skips option help if help message is not specified." do
|
321
|
-
helpmsg = @schema.option_help()
|
322
|
-
ok {helpmsg} !~ /debug/
|
323
|
-
end
|
324
|
-
|
325
|
-
spec "[!to1th] includes all option help when `all` is true." do
|
326
|
-
helpmsg = @schema.option_help(nil, all: true)
|
327
|
-
ok {helpmsg} =~ /debug/
|
328
|
-
ok {helpmsg} == <<END
|
329
|
-
-h, --help : show help message.
|
330
|
-
--version : print version
|
331
|
-
-f, --file=<FILE> : filename
|
332
|
-
-i, --indent[=<WIDTH>] : enable indent
|
333
|
-
-d, --debug :
|
334
|
-
END
|
335
|
-
end
|
336
|
-
|
337
|
-
spec "[!848rm] supports multi-lines help message." do
|
338
|
-
sc = Benry::CmdOpt::Schema.new
|
339
|
-
sc.add(:mode, "-m, --mode=<MODE>", "output mode",
|
340
|
-
detail: <<"END")
|
341
|
-
v, verbose: print many output
|
342
|
-
q, quiet: print litte output
|
343
|
-
c, compact: print summary output
|
344
|
-
END
|
345
|
-
actual = sc.option_help()
|
346
|
-
expected = <<END
|
347
|
-
-m, --mode=<MODE> : output mode
|
348
|
-
v, verbose: print many output
|
349
|
-
q, quiet: print litte output
|
350
|
-
c, compact: print summary output
|
351
|
-
END
|
352
|
-
ok {actual} == expected
|
353
|
-
end
|
354
|
-
|
355
|
-
spec "[!a4qe4] option should not be hidden if description is empty string." do
|
356
|
-
sc = Benry::CmdOpt::Schema.new
|
357
|
-
sc.add(:debug , "-D", nil) # hidden
|
358
|
-
sc.add(:trace, "-T", "trace", hidden: true) # hidden
|
359
|
-
sc.add(:what , "-W", "") # NOT hidden!
|
360
|
-
ok {sc.option_help()} == <<END
|
361
|
-
-W :
|
362
|
-
END
|
363
|
-
end
|
364
|
-
|
365
|
-
fixture :schema_with_importance do
|
366
|
-
sc = Benry::CmdOpt::Schema.new
|
367
|
-
sc.add(:help , "-h, --help" , "help message")
|
368
|
-
sc.add(:trace , "-T, --trace", "trace" , important: true)
|
369
|
-
sc.add(:debug , "-D, --debug", "debug mode" , important: false)
|
370
|
-
sc.add(:quiet , "-q, --quiet", "quiet mode")
|
371
|
-
sc
|
372
|
-
end
|
373
|
-
|
374
|
-
spec "[!jrwb6] decorates help message according to `important:` value of option." do
|
375
|
-
|schema_with_importance|
|
376
|
-
sc = schema_with_importance
|
377
|
-
ok {sc.option_help()} == <<END
|
378
|
-
-h, --help : help message
|
379
|
-
\e[1m -T, --trace : trace\e[0m
|
380
|
-
\e[2m -D, --debug : debug mode\e[0m
|
381
|
-
-q, --quiet : quiet mode
|
382
|
-
END
|
383
|
-
end
|
384
|
-
|
385
|
-
spec "[!9nlfb] not decorate help message when stdout is not a tty." do
|
386
|
-
|schema_with_importance|
|
387
|
-
sc = schema_with_importance
|
388
|
-
output = nil
|
389
|
-
capture_sio() {
|
390
|
-
ok {$stdout}.NOT.tty?
|
391
|
-
output = sc.option_help()
|
392
|
-
}
|
393
|
-
ok {output} == <<END
|
394
|
-
-h, --help : help message
|
395
|
-
-T, --trace : trace
|
396
|
-
-D, --debug : debug mode
|
397
|
-
-q, --quiet : quiet mode
|
398
|
-
END
|
399
|
-
end
|
400
|
-
|
401
|
-
end
|
402
|
-
|
403
|
-
|
404
|
-
topic '#_default_format()' do
|
405
|
-
|
406
|
-
before do
|
407
|
-
sc = Benry::CmdOpt::Schema.new
|
408
|
-
sc.add(:help , "-h, --help" , "show help message.")
|
409
|
-
sc.add(:version, " --version" , "print version")
|
410
|
-
sc.add(:file , "-f, --file=<FILE>" , "filename")
|
411
|
-
sc.add(:indent , "-i, --indent[=<WIDTH>]", "enable indent", type: Integer)
|
412
|
-
sc.add(:debug , "-d, --debug" , nil)
|
413
|
-
@schema = sc
|
414
|
-
end
|
415
|
-
|
416
|
-
spec "[!kkh9t] returns format string." do
|
417
|
-
ret = @schema.__send__(:_default_format)
|
418
|
-
ok {ret} == " %-22s : %s"
|
419
|
-
end
|
420
|
-
|
421
|
-
spec "[!hr45y] detects preffered option width." do
|
422
|
-
ret = @schema.__send__(:_default_format, 10, 20)
|
423
|
-
ok {ret} == " %-20s : %s"
|
424
|
-
ret = @schema.__send__(:_default_format, 30, 40)
|
425
|
-
ok {ret} == " %-30s : %s"
|
426
|
-
ret = @schema.__send__(:_default_format, 10, 40)
|
427
|
-
ok {ret} == " %-22s : %s"
|
428
|
-
end
|
429
|
-
|
430
|
-
spec "[!bmr7d] changes min_with according to options." do
|
431
|
-
sc = Benry::CmdOpt::Schema.new
|
432
|
-
sc.add(:help , '-h', "help")
|
433
|
-
sc.add(:version, '-v', "version")
|
434
|
-
ok {sc.__send__(:_default_format, nil, 40)} == " %-8s : %s"
|
435
|
-
#
|
436
|
-
sc.add(:file , '-f <FILE>', "filename")
|
437
|
-
ok {sc.__send__(:_default_format, nil, 40)} == " %-14s : %s"
|
438
|
-
#
|
439
|
-
sc.add(:force , '--force', "forcedly")
|
440
|
-
ok {sc.__send__(:_default_format, nil, 40)} == " %-14s : %s"
|
441
|
-
#
|
442
|
-
sc.add(:mode , '-m, --mode=<MODE>', "verbose/quiet")
|
443
|
-
ok {sc.__send__(:_default_format, nil, 40)} == " %-20s : %s"
|
444
|
-
end
|
445
|
-
|
446
|
-
end
|
447
|
-
|
448
|
-
|
449
|
-
topic '#_preferred_option_width()' do
|
450
|
-
|
451
|
-
spec "[!kl91t] shorten option help min width when only single options which take no arg." do
|
452
|
-
sc = Benry::CmdOpt::Schema.new
|
453
|
-
sc.add(:help , '-h', "help")
|
454
|
-
sc.add(:version, '-v', "version")
|
455
|
-
ok {sc.__send__(:_preferred_option_width)} == 8
|
456
|
-
end
|
457
|
-
|
458
|
-
spec "[!0koqb] widen option help min width when any option takes an arg." do
|
459
|
-
sc = Benry::CmdOpt::Schema.new
|
460
|
-
sc.add(:help , '-h', "help")
|
461
|
-
sc.add(:indent , '-i[<N>]', "indent")
|
462
|
-
ok {sc.__send__(:_preferred_option_width)} == 14
|
463
|
-
end
|
464
|
-
|
465
|
-
spec "[!kl91t] widen option help min width when long option exists." do
|
466
|
-
sc = Benry::CmdOpt::Schema.new
|
467
|
-
sc.add(:help , '-h', "help")
|
468
|
-
sc.add(:version, '-v, --version', "version")
|
469
|
-
ok {sc.__send__(:_preferred_option_width)} == 14
|
470
|
-
#
|
471
|
-
sc.add(:file, '--file=<FILE>', "filename")
|
472
|
-
ok {sc.__send__(:_preferred_option_width)} == 20
|
473
|
-
end
|
474
|
-
|
475
|
-
end
|
476
|
-
|
477
|
-
|
478
|
-
topic '#to_s()' do
|
479
|
-
|
480
|
-
spec "[!rrapd] '#to_s' is an alias to '#option_help()'." do
|
481
|
-
schema = Benry::CmdOpt::Schema.new
|
482
|
-
schema.add(:help , "-h, --help" , "show help message")
|
483
|
-
schema.add(:version, " --version" , "print version")
|
484
|
-
ok {schema.to_s} == schema.option_help()
|
485
|
-
end
|
486
|
-
|
487
|
-
end
|
488
|
-
|
489
|
-
|
490
|
-
topic '#each_option_and_desc()' do
|
491
|
-
|
492
|
-
before do
|
493
|
-
sc = Benry::CmdOpt::Schema.new
|
494
|
-
sc.add(:help, "-h, --help", "show help message")
|
495
|
-
sc.add(:version, " --version", "print version")
|
496
|
-
sc.add(:debug , "-d, --debug" , nil) # hidden
|
497
|
-
sc.add(:DEBUG , "-D, --DEBUG" , "debug mode", hidden: true) # hidden
|
498
|
-
@schema = sc
|
499
|
-
end
|
500
|
-
|
501
|
-
spec "[!4b911] yields each optin definition str and help message." do
|
502
|
-
pairs = []
|
503
|
-
@schema.each_option_and_desc {|opt, desc| pairs << [opt, desc] }
|
504
|
-
ok {pairs} == [
|
505
|
-
["-h, --help" , "show help message"], # not hiddden
|
506
|
-
[" --version" , "print version"], # not hidden
|
507
|
-
]
|
508
|
-
end
|
509
|
-
|
510
|
-
spec "[!cl8zy] when 'all' flag is false, not yield hidden items." do
|
511
|
-
pairs = []
|
512
|
-
@schema.each_option_and_desc(all: false) {|opt, desc| pairs << [opt, desc] }
|
513
|
-
ok {pairs} == [
|
514
|
-
["-h, --help" , "show help message"], # not hiddden
|
515
|
-
[" --version" , "print version"], # not hidden
|
516
|
-
]
|
517
|
-
end
|
518
|
-
|
519
|
-
spec "[!tc4bk] when 'all' flag is true, yields even hidden items." do
|
520
|
-
pairs = []
|
521
|
-
@schema.each_option_and_desc(all: true) {|opt, desc| pairs << [opt, desc] }
|
522
|
-
ok {pairs} == [
|
523
|
-
["-h, --help" , "show help message"], # not hiddden
|
524
|
-
[" --version" , "print version"], # not hidden
|
525
|
-
["-d, --debug" , nil], # hidden
|
526
|
-
["-D, --DEBUG" , "debug mode"], # hidden
|
527
|
-
]
|
528
|
-
end
|
529
|
-
|
530
|
-
spec "[!03sux] returns enumerator object if block not given." do
|
531
|
-
## when 'all: true'
|
532
|
-
xs = @schema.each_option_and_desc(all: true)
|
533
|
-
ok {xs}.is_a?(Enumerator)
|
534
|
-
ok {xs.collect {|x, _| x }} == ["-h, --help", " --version", "-d, --debug", "-D, --DEBUG"]
|
535
|
-
## when 'all: false'
|
536
|
-
xs = @schema.each_option_and_desc(all: false)
|
537
|
-
ok {xs}.is_a?(Enumerator)
|
538
|
-
ok {xs.collect {|x, _| x }} == ["-h, --help", " --version"]
|
539
|
-
end
|
540
|
-
|
541
|
-
spec "[!zbxyv] returns self." do
|
542
|
-
ret = @schema.each_option_and_desc { nil }
|
543
|
-
ok {ret}.same? @schema
|
544
|
-
end
|
545
|
-
|
546
|
-
end
|
547
|
-
|
548
|
-
|
549
|
-
topic '#each()' do
|
550
|
-
|
551
|
-
before do
|
552
|
-
@schema = Benry::CmdOpt::Schema.new
|
553
|
-
@schema.add(:help , "-h, --help" , "help message")
|
554
|
-
@schema.add(:version, " --version", "print version")
|
555
|
-
end
|
556
|
-
|
557
|
-
spec "[!y4k1c] yields each option item." do
|
558
|
-
items = []
|
559
|
-
@schema.each {|x| items << x }
|
560
|
-
ok {items.length} == 2
|
561
|
-
ok {items[0]}.is_a?(Benry::CmdOpt::SchemaItem)
|
562
|
-
ok {items[1]}.is_a?(Benry::CmdOpt::SchemaItem)
|
563
|
-
ok {items[0].key} == :help
|
564
|
-
ok {items[1].key} == :version
|
565
|
-
keys = @schema.each.collect {|x| x.key }
|
566
|
-
ok {keys} == [:help, :version]
|
567
|
-
end
|
568
|
-
|
569
|
-
end
|
570
|
-
|
571
|
-
|
572
|
-
topic '#empty?()' do
|
573
|
-
|
574
|
-
spec "[!um8am] returns false if any item exists, else returns true." do
|
575
|
-
schema = Benry::CmdOpt::Schema.new
|
576
|
-
ok {schema.empty?()} == true
|
577
|
-
schema.add(:help , "-h, --help" , "help message")
|
578
|
-
ok {schema.empty?()} == false
|
579
|
-
end
|
580
|
-
|
581
|
-
spec "[!icvm1] ignores hidden items if 'all: false' kwarg specified." do
|
582
|
-
schema = Benry::CmdOpt::Schema.new
|
583
|
-
schema.add(:debug , "-D", nil)
|
584
|
-
schema.add(:trace, "-T", "trace", hidden: true)
|
585
|
-
ok {schema.empty?()} == false
|
586
|
-
ok {schema.empty?(all: true)} == false
|
587
|
-
ok {schema.empty?(all: false)} == true
|
588
|
-
end
|
589
|
-
|
590
|
-
end
|
591
|
-
|
592
|
-
|
593
|
-
topic '#get()' do
|
594
|
-
|
595
|
-
before do
|
596
|
-
@schema = Benry::CmdOpt::Schema.new
|
597
|
-
@schema.add(:help , "-h, --help" , "help message")
|
598
|
-
@schema.add(:version, " --version", "print version")
|
599
|
-
end
|
600
|
-
|
601
|
-
spec "[!3wjfp] finds option item object by key." do
|
602
|
-
item = @schema.get(:help)
|
603
|
-
ok {item.key} == :help
|
604
|
-
item = @schema.get(:version)
|
605
|
-
ok {item.key} == :version
|
606
|
-
end
|
607
|
-
|
608
|
-
spec "[!0spll] returns nil if key not found." do
|
609
|
-
ok {@schema.get(:debug)} == nil
|
610
|
-
end
|
611
|
-
|
612
|
-
end
|
613
|
-
|
614
|
-
|
615
|
-
topic '#delete()' do
|
616
|
-
|
617
|
-
before do
|
618
|
-
@schema = Benry::CmdOpt::Schema.new
|
619
|
-
@schema.add(:help , "-h, --help" , "help message")
|
620
|
-
@schema.add(:version, " --version", "print version")
|
621
|
-
end
|
622
|
-
|
623
|
-
spec "[!l86rb] deletes option item corresponding to key." do
|
624
|
-
keys = @schema.each.collect {|x| x.key }
|
625
|
-
ok {keys} == [:help, :version]
|
626
|
-
@schema.delete(:help)
|
627
|
-
keys = @schema.each.collect {|x| x.key }
|
628
|
-
ok {keys} == [:version]
|
629
|
-
end
|
630
|
-
|
631
|
-
spec "[!rq0aa] returns deleted item." do
|
632
|
-
item = @schema.delete(:version)
|
633
|
-
ok {item} != nil
|
634
|
-
ok {item.key} == :version
|
635
|
-
end
|
636
|
-
|
637
|
-
end
|
638
|
-
|
639
|
-
|
640
|
-
topic '#find_short_option()' do
|
641
|
-
|
642
|
-
before do
|
643
|
-
@schema = new_sample_schema()
|
644
|
-
end
|
645
|
-
|
646
|
-
spec "[!b4js1] returns option definition matched to short name." do
|
647
|
-
x = @schema.find_short_option('h')
|
648
|
-
ok {x.key} == :help
|
649
|
-
x = @schema.find_short_option('f')
|
650
|
-
ok {x.key} == :file
|
651
|
-
x = @schema.find_short_option('i')
|
652
|
-
ok {x.key} == :indent
|
653
|
-
end
|
654
|
-
|
655
|
-
spec "[!s4d1y] returns nil when nothing found." do
|
656
|
-
ok {@schema.find_short_option('v')} == nil
|
657
|
-
end
|
658
|
-
|
659
|
-
end
|
660
|
-
|
661
|
-
|
662
|
-
topic '#find_long_option()' do
|
663
|
-
|
664
|
-
before do
|
665
|
-
@schema = new_sample_schema()
|
666
|
-
end
|
667
|
-
|
668
|
-
spec "[!atmf9] returns option definition matched to long name." do
|
669
|
-
x = @schema.find_long_option('help')
|
670
|
-
ok {x.key} == :help
|
671
|
-
x = @schema.find_long_option('file')
|
672
|
-
ok {x.key} == :file
|
673
|
-
x = @schema.find_long_option('indent')
|
674
|
-
ok {x.key} == :indent
|
675
|
-
end
|
676
|
-
|
677
|
-
spec "[!6haoo] returns nil when nothing found." do
|
678
|
-
ok {@schema.find_long_option('lib')} == nil
|
679
|
-
end
|
680
|
-
|
681
|
-
end
|
682
|
-
|
683
|
-
|
684
|
-
end
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
topic Benry::CmdOpt::SchemaItem do
|
689
|
-
|
690
|
-
ITEMS = [
|
691
|
-
Benry::CmdOpt::SchemaItem.new(:help, "-h, --help", "help msg",
|
692
|
-
"h", "help", nil, nil),
|
693
|
-
Benry::CmdOpt::SchemaItem.new(:file, "-f, --file=<file>", "filename",
|
694
|
-
"f", "file", "<file>", true),
|
695
|
-
Benry::CmdOpt::SchemaItem.new(:indent, "-i, --indent[=<N>]", "indent width",
|
696
|
-
"i", "indent", "<N>", false),
|
697
|
-
]
|
698
|
-
|
699
|
-
|
700
|
-
topic '#initialize()' do
|
701
|
-
|
702
|
-
before do
|
703
|
-
@schema = Benry::CmdOpt::Schema.new
|
704
|
-
end
|
705
|
-
|
706
|
-
spec "[!nn4cp] freezes enum object." do
|
707
|
-
item = Benry::CmdOpt::SchemaItem.new(:foo, "--foo", "desc", nil, "foo", "<val>",
|
708
|
-
true, enum: ["x", "y", "z"])
|
709
|
-
ok {item.enum} == ["x", "y", "z"]
|
710
|
-
ok {item.enum}.frozen?
|
711
|
-
end
|
712
|
-
|
713
|
-
case_when "[!wy2iv] when 'type:' specified..." do
|
714
|
-
|
715
|
-
spec "[!7xmr5] raises SchemaError when type is not registered." do
|
716
|
-
sc = @schema
|
717
|
-
pr = proc {
|
718
|
-
sc.add(:indent, "-i, --indent[=<WIDTH>]", "indent width", type: Array)
|
719
|
-
}
|
720
|
-
ok {pr}.raise?(Benry::CmdOpt::SchemaError,
|
721
|
-
"Array: Unregistered type.")
|
722
|
-
end
|
723
|
-
|
724
|
-
spec "[!s2aaj] raises SchemaError when option has no params but type specified." do
|
725
|
-
sc = @schema
|
726
|
-
pr = proc {
|
727
|
-
sc.add(:indent, "-i, --indent", "indent width", type: Integer)
|
728
|
-
}
|
729
|
-
ok {pr}.raise?(Benry::CmdOpt::SchemaError,
|
730
|
-
"Integer: Type specified in spite of option has no params.")
|
731
|
-
end
|
732
|
-
|
733
|
-
spec "[!sz8x2] not raise error when no params but value specified." do
|
734
|
-
sc = @schema
|
735
|
-
pr = proc {
|
736
|
-
sc.add(:indent, "-i, --indent", "indent width", type: Integer, value: 0)
|
737
|
-
}
|
738
|
-
ok {pr}.NOT.raise?(Exception)
|
739
|
-
end
|
740
|
-
|
741
|
-
spec "[!70ogf] not raise error when no params but TrueClass specified." do
|
742
|
-
sc = @schema
|
743
|
-
pr = proc {
|
744
|
-
sc.add(:indent, "-i, --indent", "indent width", type: TrueClass)
|
745
|
-
}
|
746
|
-
ok {pr}.NOT.raise?(Exception)
|
747
|
-
end
|
748
|
-
|
749
|
-
end
|
750
|
-
|
751
|
-
case_when "[!6y8s2] when 'rexp:' specified..." do
|
752
|
-
|
753
|
-
spec "[!bi2fh] raises SchemaError when pattern is not a regexp." do
|
754
|
-
sc = @schema
|
755
|
-
pr = proc {
|
756
|
-
sc.add(:indent, "-x, --indent[=<WIDTH>]", "indent width", rexp: '\A\d+\z')
|
757
|
-
}
|
758
|
-
ok {pr}.raise?(Benry::CmdOpt::SchemaError,
|
759
|
-
'"\\\\A\\\\d+\\\\z": Regexp pattern expected.')
|
760
|
-
end
|
761
|
-
|
762
|
-
spec "[!01fmt] raises SchmeaError when option has no params but pattern specified." do
|
763
|
-
sc = @schema
|
764
|
-
pr = proc {
|
765
|
-
sc.add(:indent, "-i, --indent", "indent width", rexp: /\A\d+\z/)
|
766
|
-
}
|
767
|
-
ok {pr}.raise?(Benry::CmdOpt::SchemaError,
|
768
|
-
'/\A\d+\z/: Regexp pattern specified in spite of option has no params.')
|
769
|
-
end
|
770
|
-
|
771
|
-
end
|
772
|
-
|
773
|
-
case_when "[!5nrvq] when 'enum:' specified..." do
|
774
|
-
|
775
|
-
spec "[!melyd] raises SchemaError when enum is not an Array nor Set." do
|
776
|
-
sc = @schema
|
777
|
-
sc.add(:indent, "-i <N>", "indent width", enum: ["2", "4", "8"])
|
778
|
-
sc.add(:indent, "-i <N>", "indent width", enum: Set.new(["2", "4", "8"]))
|
779
|
-
pr = proc {
|
780
|
-
sc.add(:indent, "-i <N>", "indent width", enum: "2,4,8")
|
781
|
-
}
|
782
|
-
ok {pr}.raise?(Benry::CmdOpt::SchemaError,
|
783
|
-
'"2,4,8": Array or set expected.')
|
784
|
-
end
|
785
|
-
|
786
|
-
spec "[!xqed8] raises SchemaError when enum specified for no param option." do
|
787
|
-
sc = @schema
|
788
|
-
pr = proc {
|
789
|
-
sc.add(:indent, "-i", "enable indent", enum: [2, 4, 8])
|
790
|
-
}
|
791
|
-
ok {pr}.raise?(Benry::CmdOpt::SchemaError,
|
792
|
-
"[2, 4, 8]: Enum specified in spite of option has no params.")
|
793
|
-
end
|
794
|
-
|
795
|
-
spec "[!zuthh] raises SchemaError when enum element value is not instance of type class." do
|
796
|
-
sc = @schema
|
797
|
-
pr = proc {
|
798
|
-
sc.add(:indent, "-i <N>", "enable indent", type: Integer, enum: ['2', '4', '8'])
|
799
|
-
}
|
800
|
-
ok {pr}.raise?(Benry::CmdOpt::SchemaError,
|
801
|
-
'["2", "4", "8"]: Enum element value should be instance of Integer, but "2" is not.')
|
802
|
-
end
|
803
|
-
|
804
|
-
end
|
805
|
-
|
806
|
-
case_when "[!hk4nw] when 'range:' specified..." do
|
807
|
-
|
808
|
-
spec "[!z20ky] raises SchemaError when range is not a Range object." do
|
809
|
-
pr = proc {
|
810
|
-
@schema.add(:indent, "-i <N>", "indent", type: Integer, range: [1,8])
|
811
|
-
}
|
812
|
-
ok {pr}.raise?(Benry::CmdOpt::SchemaError,
|
813
|
-
"[1, 8]: Range object expected.")
|
814
|
-
end
|
815
|
-
|
816
|
-
spec "[!gp025] raises SchemaError when range specified with `type: TrueClass`." do
|
817
|
-
pr = proc {
|
818
|
-
@schema.add(:indent, "-i <N>", "indent", type: TrueClass, range: 0..1)
|
819
|
-
}
|
820
|
-
ok {pr}.raise?(Benry::CmdOpt::SchemaError,
|
821
|
-
"0..1: Range is not available with `type: TrueClass`.")
|
822
|
-
end
|
823
|
-
|
824
|
-
spec "[!7njd5] range beginning/end value should be expected type." do
|
825
|
-
pr = proc {
|
826
|
-
@schema.add(:indent, "-i <N>", "indent", range: (1..8))
|
827
|
-
}
|
828
|
-
ok {pr}.raise?(Benry::CmdOpt::SchemaError,
|
829
|
-
"1..8: Range value should be String, but not.")
|
830
|
-
pr = proc {
|
831
|
-
@schema.add(:indent, "-i <N>", "indent", type: Date, range: (1..8))
|
832
|
-
}
|
833
|
-
ok {pr}.raise?(Benry::CmdOpt::SchemaError,
|
834
|
-
"1..8: Range value should be Date, but not.")
|
835
|
-
end
|
836
|
-
|
837
|
-
spec "[!uymig] range object can be endless." do
|
838
|
-
begin
|
839
|
-
range1 = eval "(1..)" # Ruby >= 2.6
|
840
|
-
range2 = eval "(..3)" # Ruby >= 2.6
|
841
|
-
rescue SyntaxError
|
842
|
-
range1 = nil # Ruby < 2.6
|
843
|
-
range2 = nil # Ruby < 2.6
|
844
|
-
end
|
845
|
-
if range1
|
846
|
-
pr = proc {
|
847
|
-
@schema.add(:indent1, "-i <N>", "indent", type: Integer, range: range1)
|
848
|
-
@schema.add(:indent2, "-j <N>", "indent", type: Integer, range: range2)
|
849
|
-
}
|
850
|
-
pr.call
|
851
|
-
ok {pr}.NOT.raise?(Exception)
|
852
|
-
end
|
853
|
-
end
|
854
|
-
|
855
|
-
end
|
856
|
-
|
857
|
-
case_when "[!a0g52] when 'value:' specified..." do
|
858
|
-
|
859
|
-
spec "[!435t6] raises SchemaError when 'value:' is specified on argument-required option." do
|
860
|
-
sc = @schema
|
861
|
-
pr = proc {
|
862
|
-
sc.add(:flag, "--flag=<on|off>", "flag", type: TrueClass, value: true)
|
863
|
-
}
|
864
|
-
ok {pr}.raise?(Benry::CmdOpt::SchemaError,
|
865
|
-
"true: 'value:' is meaningless when option has required argument (hint: change to optional argument instead).")
|
866
|
-
end
|
867
|
-
|
868
|
-
spec "[!6vwqv] raises SchemaError when type is TrueClass but value is not true nor false." do
|
869
|
-
sc = @schema
|
870
|
-
pr = proc {
|
871
|
-
sc.add(:flag, "--flag[=<on|off>]", "flag", type: TrueClass, value: 0)
|
872
|
-
}
|
873
|
-
ok {pr}.raise?(Benry::CmdOpt::SchemaError,
|
874
|
-
"0: Value should be true or false when `type: TrueClass` specified.")
|
875
|
-
end
|
876
|
-
|
877
|
-
spec "[!c6i2o] raises SchemaError when value is not a kind of type." do
|
878
|
-
sc = @schema
|
879
|
-
pr = proc {
|
880
|
-
sc.add(:flag, "--flag[=<on|off>]", "flag", type: Integer, value: false)
|
881
|
-
}
|
882
|
-
ok {pr}.raise?(Benry::CmdOpt::SchemaError,
|
883
|
-
"Type mismatched between `type: Integer` and `value: false`.")
|
884
|
-
end
|
885
|
-
|
886
|
-
spec "[!lnhp6] not raise error when type is not specified." do
|
887
|
-
sc = @schema
|
888
|
-
pr = proc {
|
889
|
-
sc.add(:flag, "--flag[=<on|off>]", "flag", value: false)
|
890
|
-
}
|
891
|
-
ok {pr}.NOT.raise?(Exception)
|
892
|
-
end
|
893
|
-
|
894
|
-
spec "[!6xb8o] value should be included in enum values." do
|
895
|
-
sc = @schema
|
896
|
-
pr = proc {
|
897
|
-
sc.add(:lang, "--lang[=<en|fr|it>]", "language", enum: ["en", "fr", "it"], value: "ja")
|
898
|
-
}
|
899
|
-
ok {pr}.raise?(Benry::CmdOpt::SchemaError,
|
900
|
-
"ja: Value should be included in enum values, but not.")
|
901
|
-
end
|
902
|
-
|
903
|
-
end
|
904
|
-
|
905
|
-
end
|
906
|
-
|
907
|
-
|
908
|
-
topic '#required?' do
|
909
|
-
|
910
|
-
spec "[!svxny] returns nil if option takes no arguments." do
|
911
|
-
item, _, _ = ITEMS
|
912
|
-
ok {item.required?} == nil
|
913
|
-
end
|
914
|
-
|
915
|
-
spec "[!togcx] returns true if argument is required." do
|
916
|
-
_, item, _ = ITEMS
|
917
|
-
ok {item.required?} == true
|
918
|
-
end
|
919
|
-
|
920
|
-
spec "[!uwbgc] returns false if argument is optional." do
|
921
|
-
_, _, item = ITEMS
|
922
|
-
ok {item.required?} == false
|
923
|
-
end
|
924
|
-
|
925
|
-
end
|
926
|
-
|
927
|
-
|
928
|
-
topic '#arg_requireness()' do
|
929
|
-
|
930
|
-
spec "[!kmo28] returns :none if option takes no arguments." do
|
931
|
-
item, _, _ = ITEMS
|
932
|
-
ok {item.arg_requireness()} == :none
|
933
|
-
end
|
934
|
-
|
935
|
-
spec "[!s8gxl] returns :required if argument is required." do
|
936
|
-
_, item, _ = ITEMS
|
937
|
-
ok {item.arg_requireness()} == :required
|
938
|
-
end
|
939
|
-
|
940
|
-
spec "[!owpba] returns :optional if argument is optional." do
|
941
|
-
_, _, item = ITEMS
|
942
|
-
ok {item.arg_requireness()} == :optional
|
943
|
-
end
|
944
|
-
|
945
|
-
end
|
946
|
-
|
947
|
-
|
948
|
-
topic '#hidden?()' do
|
949
|
-
|
950
|
-
spec "[!no6ov] returns true if @hidden is true." do
|
951
|
-
item = Benry::CmdOpt::SchemaItem.new(:debug, "-D", "debug mode", "D", nil, nil, nil, hidden: true)
|
952
|
-
ok {item.hidden?} == true
|
953
|
-
end
|
954
|
-
|
955
|
-
spec "[!ej8ot] returns false if @hidden is false." do
|
956
|
-
item = Benry::CmdOpt::SchemaItem.new(:debug, "-D", "debug mode", "D", nil, nil, nil, hidden: false)
|
957
|
-
ok {item.hidden?} == false
|
958
|
-
end
|
959
|
-
|
960
|
-
spec "[!h0uxs] returns true if desc is nil." do
|
961
|
-
desc = nil
|
962
|
-
item = Benry::CmdOpt::SchemaItem.new(:debug, "-D", desc, "D", nil, nil, nil)
|
963
|
-
ok {item.hidden?} == true
|
964
|
-
end
|
965
|
-
|
966
|
-
spec "[!28vzx] returns false if else." do
|
967
|
-
desc = "debug mode"
|
968
|
-
item = Benry::CmdOpt::SchemaItem.new(:debug, "-D", desc, "D", nil, nil, nil)
|
969
|
-
ok {item.hidden?} == false
|
970
|
-
end
|
971
|
-
|
972
|
-
end
|
973
|
-
|
974
|
-
|
975
|
-
topic '#important?()' do
|
976
|
-
|
977
|
-
spec "[!ua8kt] returns true/false if `important:` kwarg passed to constructor." do
|
978
|
-
item1 = Benry::CmdOpt::SchemaItem.new(:debug, "-D", "debug mode", "D", nil, nil, nil, important: true)
|
979
|
-
ok {item1.important?} == true
|
980
|
-
item2 = Benry::CmdOpt::SchemaItem.new(:debug, "-D", "debug mode", "D", nil, nil, nil, important: false)
|
981
|
-
ok {item2.important?} == false
|
982
|
-
end
|
983
|
-
|
984
|
-
spec "[!hz9sx] returns nil if `important:` kwarg not passed to constructor." do
|
985
|
-
item3 = Benry::CmdOpt::SchemaItem.new(:debug, "-D", "debug mode", "D", nil, nil, nil)
|
986
|
-
ok {item3.important?} == nil
|
987
|
-
end
|
988
|
-
|
989
|
-
end
|
990
|
-
|
991
|
-
|
992
|
-
topic '#validate_and_convert()' do
|
993
|
-
|
994
|
-
def new_item(key, optstr, desc, short, long, param, required,
|
995
|
-
type: nil, rexp: nil, enum: nil, range: nil, value: nil, &callback)
|
996
|
-
return Benry::CmdOpt::SchemaItem.new(key, optstr, desc, short, long, param, required,
|
997
|
-
type: type, rexp: rexp, enum: enum, range: range, value: value, &callback)
|
998
|
-
end
|
999
|
-
|
1000
|
-
spec "[!h0s0o] raises RuntimeError when value not matched to pattern." do
|
1001
|
-
x = new_item(:indent, "", "indent width", "i", "indent", "<WIDTH>", false, rexp: /\A\d+\z/)
|
1002
|
-
optdict = {}
|
1003
|
-
pr = proc { x.validate_and_convert("abc", optdict) }
|
1004
|
-
ok {pr}.raise?(RuntimeError, "Pattern unmatched.")
|
1005
|
-
end
|
1006
|
-
|
1007
|
-
spec "[!5jrdf] raises RuntimeError when value not in enum." do
|
1008
|
-
x = new_item(:indent, "", "indent width", "i", "indent", "<WIDTH>", false, enum: ['2', '4', '8'])
|
1009
|
-
optdict = {}
|
1010
|
-
pr = proc { x.validate_and_convert("10", optdict) }
|
1011
|
-
ok {pr}.raise?(RuntimeError, "Expected one of 2/4/8.")
|
1012
|
-
end
|
1013
|
-
|
1014
|
-
spec "[!5falp] raise RuntimeError when value not in range." do
|
1015
|
-
x = new_item(:indent, "-i[=<N>]", "indent", "i", nil, "<N>", false,
|
1016
|
-
type: Integer, range: 2..8)
|
1017
|
-
optdict = {}
|
1018
|
-
pr = proc { x.validate_and_convert("1", optdict) }
|
1019
|
-
ok {pr}.raise?(RuntimeError, "Too small (min: 2)")
|
1020
|
-
pr = proc { x.validate_and_convert("9", optdict) }
|
1021
|
-
ok {pr}.raise?(RuntimeError, "Too large (max: 8)")
|
1022
|
-
## when min==0
|
1023
|
-
x = new_item(:indent, "-i[=<N>]", "indent", "i", nil, "<N>", false,
|
1024
|
-
type: Integer, range: 0..8)
|
1025
|
-
optdict = {}
|
1026
|
-
pr = proc { x.validate_and_convert("-1", optdict) }
|
1027
|
-
ok {pr}.raise?(RuntimeError, "Positive value (>= 0) expected.")
|
1028
|
-
## when min==1
|
1029
|
-
x = new_item(:indent, "-i[=<N>]", "indent", "i", nil, "<N>", false,
|
1030
|
-
type: Integer, range: 1..8)
|
1031
|
-
optdict = {}
|
1032
|
-
pr = proc { x.validate_and_convert("0", optdict) }
|
1033
|
-
ok {pr}.raise?(RuntimeError, "Positive value (>= 1) expected.")
|
1034
|
-
end
|
1035
|
-
|
1036
|
-
spec "[!a0rej] supports endless range." do
|
1037
|
-
begin
|
1038
|
-
range1 = eval "(2..)" # Ruby >= 2.6
|
1039
|
-
range2 = eval "(..8)"
|
1040
|
-
rescue SyntaxError
|
1041
|
-
range1 = nil # Ruby < 2.6
|
1042
|
-
range2 = nil
|
1043
|
-
end
|
1044
|
-
if range1
|
1045
|
-
x = new_item(:indent, "-i[=<N>]", "indent", "i", nil, "<N>", false,
|
1046
|
-
type: Integer, range: range1)
|
1047
|
-
optdict = {}
|
1048
|
-
pr = proc { x.validate_and_convert("1", optdict) }
|
1049
|
-
ok {pr}.raise?(RuntimeError, "Too small (min: 2)")
|
1050
|
-
pr = proc { x.validate_and_convert("9", optdict) }
|
1051
|
-
ok {pr}.NOT.raise?(RuntimeError)
|
1052
|
-
end
|
1053
|
-
if range2
|
1054
|
-
x = new_item(:indent, "-i[=<N>]", "indent", "i", nil, "<N>", false,
|
1055
|
-
type: Integer, range: range2)
|
1056
|
-
optdict = {}
|
1057
|
-
pr = proc { x.validate_and_convert("1", optdict) }
|
1058
|
-
ok {pr}.NOT.raise?(RuntimeError)
|
1059
|
-
pr = proc { x.validate_and_convert("9", optdict) }
|
1060
|
-
ok {pr}.raise?(RuntimeError, "Too large (max: 8)")
|
1061
|
-
end
|
1062
|
-
end
|
1063
|
-
|
1064
|
-
spec "[!j4fuz] calls type-specific callback when type specified." do
|
1065
|
-
x = new_item(:indent, "", "indent width", "i", "indent", "<WIDTH>", false, type: Integer)
|
1066
|
-
optdict = {}
|
1067
|
-
pr = proc { x.validate_and_convert("abc", optdict) }
|
1068
|
-
ok {pr}.raise?(RuntimeError, "Integer expected.")
|
1069
|
-
end
|
1070
|
-
|
1071
|
-
spec "[!jn9z3] calls callback when callback specified." do
|
1072
|
-
called = false
|
1073
|
-
x = new_item(:indent, "", "indent width", "i", "indent", "<WIDTH>", false) {|va|
|
1074
|
-
called = true
|
1075
|
-
}
|
1076
|
-
optdict = {}
|
1077
|
-
x.validate_and_convert("abc", optdict)
|
1078
|
-
ok {called} == true
|
1079
|
-
end
|
1080
|
-
|
1081
|
-
spec "[!iqalh] calls callback with different number of args according to arity." do
|
1082
|
-
args1 = nil
|
1083
|
-
x = new_item(:indent, "", "indent width", "i", "indent", "<WIDTH>", false) {|val|
|
1084
|
-
args1 = val
|
1085
|
-
}
|
1086
|
-
optdict = {}
|
1087
|
-
x.validate_and_convert("123", optdict)
|
1088
|
-
ok {args1} == "123"
|
1089
|
-
#
|
1090
|
-
args2 = nil
|
1091
|
-
x = new_item(:indent, "", "indent width", "i", "indent", "<WIDTH>", false) {|optdict, key, val|
|
1092
|
-
args2 = [optdict, key, val]
|
1093
|
-
}
|
1094
|
-
optdict = {}
|
1095
|
-
x.validate_and_convert("123", optdict)
|
1096
|
-
ok {args2} == [optdict, :indent, "123"]
|
1097
|
-
end
|
1098
|
-
|
1099
|
-
spec "[!x066l] returns new value." do
|
1100
|
-
x = new_item(:indent, "", "indent width", "i", "indent", "<WIDTH>", false, type: Integer)
|
1101
|
-
ok {x.validate_and_convert("123", {})} == 123
|
1102
|
-
#
|
1103
|
-
x = new_item(:indent, "", "indent width", "i", "indent", "<WIDTH>", false, type: Integer) {|val|
|
1104
|
-
val * 2
|
1105
|
-
}
|
1106
|
-
ok {x.validate_and_convert("123", {})} == 246
|
1107
|
-
end
|
1108
|
-
|
1109
|
-
spec "[!eafem] returns default value (if specified) instead of true value." do
|
1110
|
-
x1 = new_item(:flag, "", "desc", "f", "flag", nil, false, value: nil)
|
1111
|
-
ok {x1.validate_and_convert(true, {})} == true
|
1112
|
-
x2 = new_item(:flag, "", "desc", "f", "flag", nil, false, value: "blabla")
|
1113
|
-
ok {x2.validate_and_convert(true, {})} == "blabla"
|
1114
|
-
x3 = new_item(:flag, "", "desc", "f", "flag", nil, false, value: false)
|
1115
|
-
ok {x3.validate_and_convert(true, {})} == false
|
1116
|
-
end
|
1117
|
-
|
1118
|
-
end
|
1119
|
-
|
1120
|
-
end
|
1121
|
-
|
1122
|
-
|
1123
|
-
|
1124
|
-
topic Benry::CmdOpt::Parser do
|
1125
|
-
|
1126
|
-
|
1127
|
-
topic '#parse_options()' do
|
1128
|
-
|
1129
|
-
before do
|
1130
|
-
@parser = Benry::CmdOpt::Parser.new(new_sample_schema())
|
1131
|
-
end
|
1132
|
-
|
1133
|
-
spec "[!3wmsy] returns command option values as a dict." do
|
1134
|
-
argv = ["-h", "--version"]
|
1135
|
-
d = @parser.parse(argv)
|
1136
|
-
ok {d} == {help: true, version: true}
|
1137
|
-
end
|
1138
|
-
|
1139
|
-
spec "[!uh7j8] parses long options." do
|
1140
|
-
argv = ["--help", "--file=foo.png", "--indent=10"]
|
1141
|
-
d = @parser.parse(argv)
|
1142
|
-
ok {d} == {help: true, file: "foo.png", indent: 10}
|
1143
|
-
end
|
1144
|
-
|
1145
|
-
spec "[!nwnjc] parses short options." do
|
1146
|
-
argv = ["-h", "-f", "foo.png", "-i10"]
|
1147
|
-
d = @parser.parse(argv)
|
1148
|
-
ok {d} == {help: true, file: "foo.png", indent: 10}
|
1149
|
-
end
|
1150
|
-
|
1151
|
-
spec "[!5s5b6] treats '-' as an argument, not an option." do
|
1152
|
-
argv = ["-h", "-", "xxx", "yyy"]
|
1153
|
-
d = @parser.parse(argv)
|
1154
|
-
ok {d} == {help: true}
|
1155
|
-
ok {argv} == ["-", "xxx", "yyy"]
|
1156
|
-
end
|
1157
|
-
|
1158
|
-
spec "[!q8356] parses options even after arguments when `all: true`." do
|
1159
|
-
argv = ["-h", "arg1", "-f", "foo.png", "arg2", "-i10", "arg3"]
|
1160
|
-
d = @parser.parse(argv, all: true)
|
1161
|
-
ok {d} == {help: true, file: "foo.png", indent: 10}
|
1162
|
-
ok {argv} == ["arg1", "arg2", "arg3"]
|
1163
|
-
#
|
1164
|
-
argv = ["-h", "arg1", "-f", "foo.png", "arg2", "-i10", "arg3"]
|
1165
|
-
d = @parser.parse(argv)
|
1166
|
-
ok {d} == {help: true, file: "foo.png", indent: 10}
|
1167
|
-
ok {argv} == ["arg1", "arg2", "arg3"]
|
1168
|
-
end
|
1169
|
-
|
1170
|
-
spec "[!ryra3] doesn't parse options after arguments when `all: false`." do
|
1171
|
-
argv = ["-h", "arg1", "-f", "foo.png", "arg2", "-i10", "arg3"]
|
1172
|
-
d = @parser.parse(argv, all: false)
|
1173
|
-
ok {d} == {help: true}
|
1174
|
-
ok {argv} == ["arg1", "-f", "foo.png", "arg2", "-i10", "arg3"]
|
1175
|
-
end
|
1176
|
-
|
1177
|
-
spec "[!y04um] skips rest options when '--' found in argv." do
|
1178
|
-
argv = ["-h", "--", "-f", "foo.png", "-i10"]
|
1179
|
-
d = @parser.parse(argv)
|
1180
|
-
ok {d} == {help: true}
|
1181
|
-
ok {argv} == ["-f", "foo.png", "-i10"]
|
1182
|
-
end
|
1183
|
-
|
1184
|
-
spec "[!qpuxh] handles only OptionError when block given." do
|
1185
|
-
errmsg = nil
|
1186
|
-
errcls = nil
|
1187
|
-
@parser.parse(["-ix"]) {|err|
|
1188
|
-
errmsg = err.message
|
1189
|
-
errcls = err.class
|
1190
|
-
}
|
1191
|
-
ok {errmsg} == "-ix: Integer expected."
|
1192
|
-
ok {errcls} == Benry::CmdOpt::OptionError
|
1193
|
-
#
|
1194
|
-
sc = Benry::CmdOpt::Schema.new
|
1195
|
-
sc.add(:file, "--file=<FILE>", "file") do |val|
|
1196
|
-
File.open(val) {|f| f.read }
|
1197
|
-
end
|
1198
|
-
parser = Benry::CmdOpt::Parser.new(sc)
|
1199
|
-
pr = proc { parser.parse(["--file=/foo/bar/baz.png"]) }
|
1200
|
-
ok {pr}.raise?(Errno::ENOENT, /No such file or directory/)
|
1201
|
-
end
|
1202
|
-
|
1203
|
-
spec "[!dhpw1] returns nil when OptionError handled." do
|
1204
|
-
ret = @parser.parse(["-dx"]) {|err| 1 }
|
1205
|
-
ok {ret} == nil
|
1206
|
-
end
|
1207
|
-
|
1208
|
-
end
|
1209
|
-
|
1210
|
-
|
1211
|
-
topic '#parse_long_option()' do
|
1212
|
-
|
1213
|
-
before do
|
1214
|
-
@parser = Benry::CmdOpt::Parser.new(new_sample_schema())
|
1215
|
-
end
|
1216
|
-
|
1217
|
-
spec "[!3i994] raises OptionError when invalid long option format." do
|
1218
|
-
argv = ["--f/o/o"]
|
1219
|
-
pr = proc { @parser.parse(argv) }
|
1220
|
-
ok {pr}.raise?(Benry::CmdOpt::OptionError, "--f/o/o: Invalid long option.")
|
1221
|
-
end
|
1222
|
-
|
1223
|
-
spec "[!1ab42] invokes error handler method when unknown long option." do
|
1224
|
-
def @parser.handle_unknown_long_option(optstr, name, val)
|
1225
|
-
(@_called_ ||= []) << [optstr, name, val]
|
1226
|
-
end
|
1227
|
-
ret = @parser.parse(["--xx=XX", "--yy=YY", "--zz"])
|
1228
|
-
ok {ret} == {}
|
1229
|
-
ok {@parser.instance_variable_get('@_called_')} == [
|
1230
|
-
["--xx=XX", "xx", "XX"],
|
1231
|
-
["--yy=YY", "yy", "YY"],
|
1232
|
-
["--zz" , "zz", nil],
|
1233
|
-
]
|
1234
|
-
end
|
1235
|
-
|
1236
|
-
spec "[!er7h4] default behavior is to raise OptionError when unknown long option." do
|
1237
|
-
argv = ["--foo"]
|
1238
|
-
pr = proc { @parser.parse(argv) }
|
1239
|
-
ok {pr}.raise?(Benry::CmdOpt::OptionError, "--foo: Unknown long option.")
|
1240
|
-
end
|
1241
|
-
|
1242
|
-
spec "[!2jd9w] raises OptionError when no arguments specified for arg required long option." do
|
1243
|
-
argv = ["--file"]
|
1244
|
-
pr = proc { @parser.parse(argv) }
|
1245
|
-
ok {pr}.raise?(Benry::CmdOpt::OptionError, "--file: Argument required.")
|
1246
|
-
end
|
1247
|
-
|
1248
|
-
spec "[!qyq8n] raises optionError when an argument specified for no arg long option." do
|
1249
|
-
argv = ["--version=1.0.0"]
|
1250
|
-
pr = proc { @parser.parse(argv) }
|
1251
|
-
ok {pr}.raise?(Benry::CmdOpt::OptionError, "--version=1.0.0: Unexpected argument.")
|
1252
|
-
end
|
1253
|
-
|
1254
|
-
spec "[!o596x] validates argument value." do
|
1255
|
-
argv = ["--indent=abc"]
|
1256
|
-
pr = proc { @parser.parse(argv) }
|
1257
|
-
ok {pr}.raise?(Benry::CmdOpt::OptionError, "--indent=abc: Integer expected.")
|
1258
|
-
#
|
1259
|
-
argv = ["--path=/foo/bar"]
|
1260
|
-
pr = proc { @parser.parse(argv) }
|
1261
|
-
ok {pr}.raise?(Benry::CmdOpt::OptionError, "--path=/foo/bar: Directory not exist.")
|
1262
|
-
|
1263
|
-
end
|
1264
|
-
|
1265
|
-
end
|
1266
|
-
|
1267
|
-
|
1268
|
-
topic '#parse_short_option()' do
|
1269
|
-
|
1270
|
-
before do
|
1271
|
-
@parser = Benry::CmdOpt::Parser.new(new_sample_schema())
|
1272
|
-
end
|
1273
|
-
|
1274
|
-
spec "[!4eh49] raises OptionError when unknown short option specified." do
|
1275
|
-
argv = ["-hxf", "foo.png"]
|
1276
|
-
pr = proc { @parser.parse(argv) }
|
1277
|
-
ok {pr}.raise?(Benry::CmdOpt::OptionError, "-x: Unknown option.")
|
1278
|
-
end
|
1279
|
-
|
1280
|
-
spec "[!utdbf] raises OptionError when argument required but not specified." do
|
1281
|
-
argv = ["-hf"]
|
1282
|
-
pr = proc { @parser.parse(argv) }
|
1283
|
-
ok {pr}.raise?(Benry::CmdOpt::OptionError, "-f: Argument required.")
|
1284
|
-
end
|
1285
|
-
|
1286
|
-
spec "[!f63hf] short option arg can be specified without space separator." do
|
1287
|
-
argv = ["-hfabc.png", "xx"]
|
1288
|
-
d = @parser.parse(argv)
|
1289
|
-
ok {d} == {help: true, file: "abc.png"}
|
1290
|
-
ok {argv} == ["xx"]
|
1291
|
-
end
|
1292
|
-
|
1293
|
-
spec "[!yjq6b] optional arg should be specified without space separator." do
|
1294
|
-
argv = ["-hi123", "xx"]
|
1295
|
-
d = @parser.parse(argv)
|
1296
|
-
ok {d} == {help: true, indent: 123}
|
1297
|
-
ok {argv} == ['xx']
|
1298
|
-
end
|
1299
|
-
|
1300
|
-
spec "[!wape4] otpional arg can be omit." do
|
1301
|
-
argv = ["-hi", "xx"]
|
1302
|
-
d = @parser.parse(argv)
|
1303
|
-
ok {d} == {help: true, indent: true}
|
1304
|
-
ok {argv} == ['xx']
|
1305
|
-
end
|
1306
|
-
|
1307
|
-
spec "[!yu0kc] validates short option argument." do
|
1308
|
-
argv = ["-iaaa"]
|
1309
|
-
pr = proc { @parser.parse(argv) }
|
1310
|
-
ok {pr}.raise?(Benry::CmdOpt::OptionError, "-iaaa: Integer expected.")
|
1311
|
-
#
|
1312
|
-
argv = ["-I", "/foo/bar"]
|
1313
|
-
pr = proc { @parser.parse(argv) }
|
1314
|
-
ok {pr}.raise?(Benry::CmdOpt::OptionError, "-I /foo/bar: Directory not exist.")
|
1315
|
-
end
|
1316
|
-
|
1317
|
-
end
|
1318
|
-
|
1319
|
-
|
1320
|
-
topic '#new_options_dict()' do
|
1321
|
-
|
1322
|
-
spec "[!vm6h0] returns new hash object." do
|
1323
|
-
parser = Benry::CmdOpt::Parser.new(new_sample_schema())
|
1324
|
-
ret = parser.__send__(:new_options_dict)
|
1325
|
-
ok {ret}.is_a?(Hash)
|
1326
|
-
ok {ret} == {}
|
1327
|
-
end
|
1328
|
-
|
1329
|
-
end
|
1330
|
-
|
1331
|
-
|
1332
|
-
topic '#handle_unknown_long_option()' do
|
1333
|
-
|
1334
|
-
spec "[!0q78a] raises OptionError." do
|
1335
|
-
parser = Benry::CmdOpt::Parser.new(new_sample_schema())
|
1336
|
-
pr = proc {
|
1337
|
-
parser.__send__(:handle_unknown_long_option, "--xx=XX", "xx", "XX")
|
1338
|
-
}
|
1339
|
-
ok {pr}.raise?(Benry::CmdOpt::OptionError, "--xx=XX: Unknown long option.")
|
1340
|
-
end
|
1341
|
-
|
1342
|
-
end
|
1343
|
-
|
1344
|
-
|
1345
|
-
end
|
1346
|
-
|
1347
|
-
|
1348
|
-
|
1349
12
|
topic Benry::CmdOpt do
|
1350
13
|
|
1351
14
|
|
@@ -1509,192 +172,4 @@ END
|
|
1509
172
|
end
|
1510
173
|
|
1511
174
|
|
1512
|
-
|
1513
|
-
topic Benry::CmdOpt::Facade do
|
1514
|
-
|
1515
|
-
|
1516
|
-
topic '#add()' do
|
1517
|
-
|
1518
|
-
spec "[!vmb3r] defines command option." do
|
1519
|
-
cmdopt = Benry::CmdOpt.new()
|
1520
|
-
cmdopt.add(:help, "-h, --help", "show help message", detail: "(text)", tag: :important)
|
1521
|
-
items = cmdopt.instance_eval { @schema.instance_variable_get('@items') }
|
1522
|
-
ok {items}.is_a?(Array)
|
1523
|
-
ok {items.length} == 1
|
1524
|
-
ok {items[0].key} == :help
|
1525
|
-
ok {items[0].short} == 'h'
|
1526
|
-
ok {items[0].long} == 'help'
|
1527
|
-
ok {items[0].desc} == 'show help message'
|
1528
|
-
ok {items[0].detail} == '(text)'
|
1529
|
-
ok {items[0].tag} == :important
|
1530
|
-
end
|
1531
|
-
|
1532
|
-
spec "[!71cvg] type, rexp, enum, and range are can be passed as positional args as well as keyword args." do
|
1533
|
-
cmdopt = Benry::CmdOpt.new()
|
1534
|
-
cmdopt.add(:key, "--optdef[=xx]", "desc", Integer, /\A\d+\z/, [2,4,8], (2..8), value: 4)
|
1535
|
-
items = cmdopt.instance_eval { @schema.instance_variable_get('@items') }
|
1536
|
-
item = items.first
|
1537
|
-
ok {item.type} == Integer
|
1538
|
-
ok {item.rexp} == /\A\d+\z/
|
1539
|
-
ok {item.enum} == [2,4,8]
|
1540
|
-
ok {item.range} == (2..8)
|
1541
|
-
ok {item.value} == 4
|
1542
|
-
end
|
1543
|
-
|
1544
|
-
spec "[!tu4k3] returns self." do
|
1545
|
-
cmdopt = Benry::CmdOpt.new()
|
1546
|
-
x = cmdopt.add(:version, "-v, --version", "version")
|
1547
|
-
ok {x}.same?(cmdopt)
|
1548
|
-
end
|
1549
|
-
|
1550
|
-
end
|
1551
|
-
|
1552
|
-
|
1553
|
-
topic '#option_help()' do
|
1554
|
-
|
1555
|
-
before do
|
1556
|
-
@cmdopt = Benry::CmdOpt.new
|
1557
|
-
@cmdopt.add(:help , "-h, --help" , "show help message")
|
1558
|
-
@cmdopt.add(:version, " --version" , "print version")
|
1559
|
-
@cmdopt.add(:file , "-f, --file=<FILE>" , "filename")
|
1560
|
-
end
|
1561
|
-
|
1562
|
-
spec "[!dm4p8] returns option help message." do
|
1563
|
-
helpmsg = @cmdopt.option_help()
|
1564
|
-
ok {helpmsg} == <<END
|
1565
|
-
-h, --help : show help message
|
1566
|
-
--version : print version
|
1567
|
-
-f, --file=<FILE> : filename
|
1568
|
-
END
|
1569
|
-
end
|
1570
|
-
|
1571
|
-
end
|
1572
|
-
|
1573
|
-
|
1574
|
-
topic '#to_s()' do
|
1575
|
-
|
1576
|
-
spec "[!s61vo] '#to_s' is an alias to '#option_help()'." do
|
1577
|
-
cmdopt = Benry::CmdOpt.new
|
1578
|
-
cmdopt.add(:help , "-h, --help" , "show help message")
|
1579
|
-
cmdopt.add(:version, " --version" , "print version")
|
1580
|
-
ok {cmdopt.to_s} == cmdopt.option_help()
|
1581
|
-
end
|
1582
|
-
|
1583
|
-
end
|
1584
|
-
|
1585
|
-
|
1586
|
-
topic '#each_option_and_desc()' do
|
1587
|
-
|
1588
|
-
before do
|
1589
|
-
@cmdopt = Benry::CmdOpt.new
|
1590
|
-
@cmdopt.add(:help , "-h, --help" , "show help message")
|
1591
|
-
@cmdopt.add(:version, " --version" , "print version")
|
1592
|
-
@cmdopt.add(:debug , "-D" , nil) # hidden option
|
1593
|
-
@cmdopt.add(:trace , "-T" , "trace", hidden: true) # hidden option
|
1594
|
-
end
|
1595
|
-
|
1596
|
-
spec "[!bw9qx] yields each option definition string and help message." do
|
1597
|
-
pairs = []
|
1598
|
-
@cmdopt.each_option_and_desc {|opt, desc| pairs << [opt, desc] }
|
1599
|
-
ok {pairs} == [
|
1600
|
-
["-h, --help" , "show help message"],
|
1601
|
-
[" --version", "print version"],
|
1602
|
-
]
|
1603
|
-
end
|
1604
|
-
|
1605
|
-
spec "[!kunfw] yields all items (including hidden items) if `all: true` specified." do
|
1606
|
-
## when 'all: true'
|
1607
|
-
pairs = []
|
1608
|
-
@cmdopt.each_option_and_desc(all: true) {|opt, desc| pairs << [opt, desc] }
|
1609
|
-
ok {pairs} == [
|
1610
|
-
["-h, --help" , "show help message"],
|
1611
|
-
[" --version", "print version"],
|
1612
|
-
["-D" , nil],
|
1613
|
-
["-T" , "trace"],
|
1614
|
-
]
|
1615
|
-
## when 'all: false'
|
1616
|
-
pairs = []
|
1617
|
-
@cmdopt.each_option_and_desc(all: false) {|opt, desc| pairs << [opt, desc] }
|
1618
|
-
ok {pairs} == [
|
1619
|
-
["-h, --help" , "show help message"],
|
1620
|
-
[" --version", "print version"],
|
1621
|
-
]
|
1622
|
-
end
|
1623
|
-
|
1624
|
-
spec "[!wght5] returns enumerator object if block not given." do
|
1625
|
-
## when 'all: true'
|
1626
|
-
xs = @cmdopt.each_option_and_desc(all: true)
|
1627
|
-
ok {xs}.is_a?(Enumerator)
|
1628
|
-
ok {xs.collect {|x, _| x }} == ["-h, --help", " --version", "-D", "-T"]
|
1629
|
-
## when 'all: false'
|
1630
|
-
xs = @cmdopt.each_option_and_desc(all: false)
|
1631
|
-
ok {xs}.is_a?(Enumerator)
|
1632
|
-
ok {xs.collect {|x, _| x }} == ["-h, --help", " --version"]
|
1633
|
-
end
|
1634
|
-
|
1635
|
-
end
|
1636
|
-
|
1637
|
-
|
1638
|
-
topic '#parse()' do
|
1639
|
-
|
1640
|
-
before do
|
1641
|
-
@cmdopt = Benry::CmdOpt.new()
|
1642
|
-
@cmdopt.add(:file, "-f, --file=<FILE>", "file") do |val|
|
1643
|
-
File.open(val) {|f| f.read }
|
1644
|
-
end
|
1645
|
-
@cmdopt.add(:debug, "-d, --debug[=<LEVEL>]", "debug", type: Integer)
|
1646
|
-
end
|
1647
|
-
|
1648
|
-
spec "[!7gc2m] parses command options." do
|
1649
|
-
args = ["-d", "x", "y"]
|
1650
|
-
@cmdopt.parse(args)
|
1651
|
-
ok {args} == ["x", "y"]
|
1652
|
-
end
|
1653
|
-
|
1654
|
-
spec "[!no4xu] returns option values as dict." do
|
1655
|
-
args = ["-d", "x"]
|
1656
|
-
ok {@cmdopt.parse(args)} == {:debug=>true}
|
1657
|
-
end
|
1658
|
-
|
1659
|
-
spec "[!areof] handles only OptionError when block given." do
|
1660
|
-
errmsg = nil
|
1661
|
-
errcls = nil
|
1662
|
-
@cmdopt.parse(["-dx"]) {|err|
|
1663
|
-
errmsg = err.message
|
1664
|
-
errcls = err.class
|
1665
|
-
}
|
1666
|
-
ok {errmsg} == "-dx: Integer expected."
|
1667
|
-
ok {errcls} == Benry::CmdOpt::OptionError
|
1668
|
-
#
|
1669
|
-
pr = proc do
|
1670
|
-
@cmdopt.parse(["-f", "/foo/bar/baz.png"])
|
1671
|
-
end
|
1672
|
-
ok {pr}.raise?(Errno::ENOENT, /No such file or directory/)
|
1673
|
-
end
|
1674
|
-
|
1675
|
-
spec "[!peuva] returns nil when OptionError handled." do
|
1676
|
-
ret = @cmdopt.parse(["-dx"]) {|err| 1 }
|
1677
|
-
ok {ret} == nil
|
1678
|
-
end
|
1679
|
-
|
1680
|
-
spec "[!za9at] parses options only before args when `all: false`." do
|
1681
|
-
argv = ["aaa", "-d3", "bbb"]
|
1682
|
-
#
|
1683
|
-
argv1 = argv.dup
|
1684
|
-
opts1 = @cmdopt.parse(argv1)
|
1685
|
-
ok {opts1} == {:debug=>3}
|
1686
|
-
ok {argv1} == ["aaa", "bbb"]
|
1687
|
-
#
|
1688
|
-
argv2 = argv.dup
|
1689
|
-
opts2 = @cmdopt.parse(argv2, all: false)
|
1690
|
-
ok {opts2} == {}
|
1691
|
-
ok {argv2} == ["aaa", "-d3", "bbb"]
|
1692
|
-
end
|
1693
|
-
|
1694
|
-
end
|
1695
|
-
|
1696
|
-
|
1697
|
-
end
|
1698
|
-
|
1699
|
-
|
1700
175
|
end
|