benry-cmdopt 2.3.0 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,294 @@
1
+ # -*- coding: utf-8 -*-
2
+ # frozen_string_literal: true
3
+
4
+ require_relative './shared'
5
+
6
+
7
+ Oktest.scope do
8
+
9
+
10
+ def new_sample_schema()
11
+ sc = Benry::CmdOpt::Schema.new
12
+ sc.add(:help , "-h, --help" , "show help message.")
13
+ sc.add(:version, "--version" , "print version")
14
+ sc.add(:file , "-f, --file=<FILE>" , "filename")
15
+ sc.add(:indent , "-i, --indent[=<WIDTH>]", "enable indent", type: Integer)
16
+ sc.add(:mode , "-m, --mode=<MODE>" , "mode", enum: ['verbose', 'quiet'])
17
+ sc.add(:include, "-I, --include=<PATH>" , "include path (multiple ok)", multiple: true)
18
+ sc.add(:libpath, "-L, --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
+ topic Benry::CmdOpt::Parser do
29
+
30
+
31
+ topic '#parse_options()' do
32
+
33
+ before do
34
+ @parser = Benry::CmdOpt::Parser.new(new_sample_schema())
35
+ end
36
+
37
+ spec "[!3wmsy] returns command option values as a dict." do
38
+ argv = ["-h", "--version"]
39
+ d = @parser.parse(argv)
40
+ ok {d} == {help: true, version: true}
41
+ end
42
+
43
+ spec "[!uh7j8] parses long options." do
44
+ argv = ["--help", "--file=foo.png", "--indent=10"]
45
+ d = @parser.parse(argv)
46
+ ok {d} == {help: true, file: "foo.png", indent: 10}
47
+ end
48
+
49
+ spec "[!nwnjc] parses short options." do
50
+ argv = ["-h", "-f", "foo.png", "-i10"]
51
+ d = @parser.parse(argv)
52
+ ok {d} == {help: true, file: "foo.png", indent: 10}
53
+ end
54
+
55
+ spec "[!5s5b6] treats '-' as an argument, not an option." do
56
+ argv = ["-h", "-", "xxx", "yyy"]
57
+ d = @parser.parse(argv)
58
+ ok {d} == {help: true}
59
+ ok {argv} == ["-", "xxx", "yyy"]
60
+ end
61
+
62
+ spec "[!q8356] parses options even after arguments when `all: true`." do
63
+ argv = ["-h", "arg1", "-f", "foo.png", "arg2", "-i10", "arg3"]
64
+ d = @parser.parse(argv, all: true)
65
+ ok {d} == {help: true, file: "foo.png", indent: 10}
66
+ ok {argv} == ["arg1", "arg2", "arg3"]
67
+ #
68
+ argv = ["-h", "arg1", "-f", "foo.png", "arg2", "-i10", "arg3"]
69
+ d = @parser.parse(argv)
70
+ ok {d} == {help: true, file: "foo.png", indent: 10}
71
+ ok {argv} == ["arg1", "arg2", "arg3"]
72
+ end
73
+
74
+ spec "[!ryra3] doesn't parse options after arguments when `all: false`." do
75
+ argv = ["-h", "arg1", "-f", "foo.png", "arg2", "-i10", "arg3"]
76
+ d = @parser.parse(argv, all: false)
77
+ ok {d} == {help: true}
78
+ ok {argv} == ["arg1", "-f", "foo.png", "arg2", "-i10", "arg3"]
79
+ end
80
+
81
+ spec "[!y04um] skips rest options when '--' found in argv." do
82
+ argv = ["-h", "--", "-f", "foo.png", "-i10"]
83
+ d = @parser.parse(argv)
84
+ ok {d} == {help: true}
85
+ ok {argv} == ["-f", "foo.png", "-i10"]
86
+ end
87
+
88
+ spec "[!qpuxh] handles only OptionError when block given." do
89
+ errmsg = nil
90
+ errcls = nil
91
+ @parser.parse(["-ix"]) {|err|
92
+ errmsg = err.message
93
+ errcls = err.class
94
+ }
95
+ ok {errmsg} == "-ix: Integer expected."
96
+ ok {errcls} == Benry::CmdOpt::OptionError
97
+ #
98
+ sc = Benry::CmdOpt::Schema.new
99
+ sc.add(:file, "--file=<FILE>", "file") do |val|
100
+ File.open(val) {|f| f.read }
101
+ end
102
+ parser = Benry::CmdOpt::Parser.new(sc)
103
+ pr = proc { parser.parse(["--file=/foo/bar/baz.png"]) }
104
+ ok {pr}.raise?(Errno::ENOENT, /No such file or directory/)
105
+ end
106
+
107
+ spec "[!dhpw1] returns nil when OptionError handled." do
108
+ ret = @parser.parse(["-dx"]) {|err| 1 }
109
+ ok {ret} == nil
110
+ end
111
+
112
+ end
113
+
114
+
115
+ topic '#parse_long_option()' do
116
+
117
+ before do
118
+ @parser = Benry::CmdOpt::Parser.new(new_sample_schema())
119
+ end
120
+
121
+ spec "[!3i994] raises OptionError when invalid long option format." do
122
+ argv = ["--f/o/o"]
123
+ pr = proc { @parser.parse(argv) }
124
+ ok {pr}.raise?(Benry::CmdOpt::OptionError, "--f/o/o: Invalid long option.")
125
+ end
126
+
127
+ spec "[!1ab42] invokes error handler method when unknown long option." do
128
+ def @parser.handle_unknown_long_option(optstr, name, val)
129
+ (@_called_ ||= []) << [optstr, name, val]
130
+ end
131
+ ret = @parser.parse(["--xx=XX", "--yy=YY", "--zz"])
132
+ ok {ret} == {}
133
+ ok {@parser.instance_variable_get('@_called_')} == [
134
+ ["--xx=XX", "xx", "XX"],
135
+ ["--yy=YY", "yy", "YY"],
136
+ ["--zz" , "zz", nil],
137
+ ]
138
+ end
139
+
140
+ spec "[!er7h4] default behavior is to raise OptionError when unknown long option." do
141
+ argv = ["--foo"]
142
+ pr = proc { @parser.parse(argv) }
143
+ ok {pr}.raise?(Benry::CmdOpt::OptionError, "--foo: Unknown long option.")
144
+ end
145
+
146
+ spec "[!2jd9w] raises OptionError when no arguments specified for arg required long option." do
147
+ argv = ["--file"]
148
+ pr = proc { @parser.parse(argv) }
149
+ ok {pr}.raise?(Benry::CmdOpt::OptionError, "--file: Argument required.")
150
+ end
151
+
152
+ spec "[!qyq8n] raises optionError when an argument specified for no arg long option." do
153
+ argv = ["--version=1.0.0"]
154
+ pr = proc { @parser.parse(argv) }
155
+ ok {pr}.raise?(Benry::CmdOpt::OptionError, "--version=1.0.0: Unexpected argument.")
156
+ end
157
+
158
+ spec "[!o596x] validates argument value." do
159
+ argv = ["--indent=abc"]
160
+ pr = proc { @parser.parse(argv) }
161
+ ok {pr}.raise?(Benry::CmdOpt::OptionError, "--indent=abc: Integer expected.")
162
+ #
163
+ argv = ["--path=/foo/bar"]
164
+ pr = proc { @parser.parse(argv) }
165
+ ok {pr}.raise?(Benry::CmdOpt::OptionError, "--path=/foo/bar: Directory not exist.")
166
+ end
167
+
168
+ spec "[!1m87b] supports multiple option." do
169
+ argv = ["--include=/foo", "--include=/bar"]
170
+ opts = @parser.parse(argv)
171
+ ok {opts} == {:include=>["/foo", "/bar"]}
172
+ ok {argv} == []
173
+ end
174
+
175
+ end
176
+
177
+
178
+ topic '#parse_short_option()' do
179
+
180
+ before do
181
+ @parser = Benry::CmdOpt::Parser.new(new_sample_schema())
182
+ end
183
+
184
+ spec "[!4eh49] raises OptionError when unknown short option specified." do
185
+ argv = ["-hxf", "foo.png"]
186
+ pr = proc { @parser.parse(argv) }
187
+ ok {pr}.raise?(Benry::CmdOpt::OptionError, "-x: Unknown option.")
188
+ end
189
+
190
+ spec "[!utdbf] raises OptionError when argument required but not specified." do
191
+ argv = ["-hf"]
192
+ pr = proc { @parser.parse(argv) }
193
+ ok {pr}.raise?(Benry::CmdOpt::OptionError, "-f: Argument required.")
194
+ end
195
+
196
+ spec "[!f63hf] short option arg can be specified without space separator." do
197
+ argv = ["-hfabc.png", "xx"]
198
+ d = @parser.parse(argv)
199
+ ok {d} == {help: true, file: "abc.png"}
200
+ ok {argv} == ["xx"]
201
+ end
202
+
203
+ spec "[!yjq6b] optional arg should be specified without space separator." do
204
+ argv = ["-hi123", "xx"]
205
+ d = @parser.parse(argv)
206
+ ok {d} == {help: true, indent: 123}
207
+ ok {argv} == ['xx']
208
+ end
209
+
210
+ spec "[!wape4] otpional arg can be omit." do
211
+ argv = ["-hi", "xx"]
212
+ d = @parser.parse(argv)
213
+ ok {d} == {help: true, indent: true}
214
+ ok {argv} == ['xx']
215
+ end
216
+
217
+ spec "[!yu0kc] validates short option argument." do
218
+ argv = ["-iaaa"]
219
+ pr = proc { @parser.parse(argv) }
220
+ ok {pr}.raise?(Benry::CmdOpt::OptionError, "-iaaa: Integer expected.")
221
+ #
222
+ argv = ["-L", "/foo/bar"]
223
+ pr = proc { @parser.parse(argv) }
224
+ ok {pr}.raise?(Benry::CmdOpt::OptionError, "-L /foo/bar: Directory not exist.")
225
+ end
226
+
227
+ spec "[!187r2] supports multiple option." do
228
+ argv = ["-I", "/foo", "-I/bar"]
229
+ opts = @parser.parse(argv)
230
+ ok {opts} == {:include=>["/foo", "/bar"]}
231
+ ok {argv} == []
232
+ end
233
+
234
+ end
235
+
236
+
237
+ topic '#new_options_dict()' do
238
+
239
+ spec "[!vm6h0] returns new hash object." do
240
+ parser = Benry::CmdOpt::Parser.new(new_sample_schema())
241
+ ret = parser.__send__(:new_options_dict)
242
+ ok {ret}.is_a?(Hash)
243
+ ok {ret} == {}
244
+ end
245
+
246
+ end
247
+
248
+
249
+ topic '#store_option_value()' do
250
+
251
+ spec "[!my86j] stores multiple values if multiple option item." do
252
+ schema = Benry::CmdOpt::Schema.new()
253
+ item = schema.add(:includes, "-I <path>", "include path", multiple: true)
254
+ parser = Benry::CmdOpt::Parser.new(schema)
255
+ optdict = {}
256
+ parser.instance_eval do
257
+ store_option_value(optdict, item, "/usr/include")
258
+ store_option_value(optdict, item, "/usr/local/include")
259
+ end
260
+ ok {optdict} == {:includes => ["/usr/include", "/usr/local/include"]}
261
+ end
262
+
263
+ spec "[!tm7xw] stores singile value if not multiple option item." do
264
+ schema = Benry::CmdOpt::Schema.new()
265
+ item = schema.add(:include, "-I <path>", "include path")
266
+ parser = Benry::CmdOpt::Parser.new(schema)
267
+ optdict = {}
268
+ parser.instance_eval do
269
+ store_option_value(optdict, item, "/usr/include")
270
+ store_option_value(optdict, item, "/usr/local/include")
271
+ end
272
+ ok {optdict} == {:include => "/usr/local/include"}
273
+ end
274
+
275
+ end
276
+
277
+
278
+ topic '#handle_unknown_long_option()' do
279
+
280
+ spec "[!0q78a] raises OptionError." do
281
+ parser = Benry::CmdOpt::Parser.new(new_sample_schema())
282
+ pr = proc {
283
+ parser.__send__(:handle_unknown_long_option, "--xx=XX", "xx", "XX")
284
+ }
285
+ ok {pr}.raise?(Benry::CmdOpt::OptionError, "--xx=XX: Unknown long option.")
286
+ end
287
+
288
+ end
289
+
290
+
291
+ end
292
+
293
+
294
+ end
data/test/run_all.rb ADDED
@@ -0,0 +1,6 @@
1
+ # -*- coding: utf-8 -*-
2
+ # frozen_string_literal: true
3
+
4
+ Dir.glob(File.dirname(__FILE__) + '/**/*_test.rb').each do |filename|
5
+ require File.absolute_path(filename)
6
+ end