pablo 1.0.3
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.tar.gz.sig +0 -0
- data/History.txt +4 -0
- data/LICENSE.txt +22 -0
- data/Manifest.txt +26 -0
- data/README.txt +61 -0
- data/lib/pablo.rb +298 -0
- data/lib/pablo/always.rb +44 -0
- data/lib/pablo/arguments.rb +76 -0
- data/lib/pablo/color.rb +57 -0
- data/lib/pablo/command.rb +71 -0
- data/lib/pablo/errors.rb +68 -0
- data/lib/pablo/expansion.rb +58 -0
- data/lib/pablo/help.rb +191 -0
- data/lib/pablo/helpers.rb +46 -0
- data/lib/pablo/option.rb +89 -0
- data/lib/pablo/parser.rb +192 -0
- data/lib/pablo/token.rb +66 -0
- data/lib/pablo/version.rb +29 -0
- data/test/fixtures/license.txt +22 -0
- data/test/fixtures/load_yaml.yml +37 -0
- data/test/fixtures/output.yml +13 -0
- data/test/help_fixtures.rb +47 -0
- data/test/test_arguments.rb +56 -0
- data/test/test_expansion.rb +62 -0
- data/test/test_output.rb +202 -0
- data/test/test_pablo.rb +115 -0
- data/test/test_parsers.rb +470 -0
- metadata +117 -0
- metadata.gz.sig +0 -0
@@ -0,0 +1,470 @@
|
|
1
|
+
###### DON'T PANIC License 1.1 ###########
|
2
|
+
#
|
3
|
+
# Don't panic, this piece of software is
|
4
|
+
# free, i.e. you can do with it whatever
|
5
|
+
# you like, including, but not limited to:
|
6
|
+
#
|
7
|
+
# * using it
|
8
|
+
# * copying it
|
9
|
+
# * (re)distributing it
|
10
|
+
# * burning/burying/shredding it
|
11
|
+
# * eating it
|
12
|
+
# * using it to obtain world domination
|
13
|
+
# * and ignoring it
|
14
|
+
#
|
15
|
+
# Under the sole condition that you
|
16
|
+
#
|
17
|
+
# * CONSIDER buying the author a strong
|
18
|
+
# brownian motion producer, say a nice
|
19
|
+
# hot cup of tea, should you ever meet
|
20
|
+
# him in person.
|
21
|
+
#
|
22
|
+
##########################################
|
23
|
+
|
24
|
+
require "test/unit"
|
25
|
+
require "pablo"
|
26
|
+
require File.join File.dirname(__FILE__), 'help_fixtures'
|
27
|
+
|
28
|
+
class TestParsers < Test::Unit::TestCase
|
29
|
+
|
30
|
+
# ------------------ always ----------------
|
31
|
+
|
32
|
+
def test_always
|
33
|
+
p = Pablo.new
|
34
|
+
worked = false
|
35
|
+
|
36
|
+
p.always do
|
37
|
+
worked = true
|
38
|
+
end
|
39
|
+
|
40
|
+
p.parse []
|
41
|
+
assert worked
|
42
|
+
end
|
43
|
+
|
44
|
+
# ------------------ command ----------------
|
45
|
+
|
46
|
+
def test_command_consume_all
|
47
|
+
p = Pablo.new
|
48
|
+
p.command :foo, :consume_all => false
|
49
|
+
p.command :bar, :consume_all => false
|
50
|
+
|
51
|
+
p.parse ['foo', 'bar']
|
52
|
+
assert p.commands[:foo]
|
53
|
+
assert p.commands[:bar]
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_single_command
|
57
|
+
worked = false
|
58
|
+
p = Pablo.new
|
59
|
+
|
60
|
+
p.command :foo do |args, pablo|
|
61
|
+
assert_equal 1, args.length
|
62
|
+
assert_equal 'bar', args[0]
|
63
|
+
worked = true
|
64
|
+
end
|
65
|
+
|
66
|
+
p.parse %w{foo bar}
|
67
|
+
assert worked
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_commands
|
71
|
+
worked = false
|
72
|
+
p = Pablo.new
|
73
|
+
|
74
|
+
p.command :foo do |args, pablo|
|
75
|
+
assert_equal 1, args.length
|
76
|
+
assert_equal 'bar', args[0]
|
77
|
+
worked = true
|
78
|
+
end
|
79
|
+
|
80
|
+
p.command :bar do
|
81
|
+
flunk 'two top-level commands called'
|
82
|
+
end
|
83
|
+
|
84
|
+
p.parse %w{foo bar}
|
85
|
+
assert worked
|
86
|
+
end
|
87
|
+
|
88
|
+
# ------------------ option -----------------
|
89
|
+
|
90
|
+
def test_option_negates
|
91
|
+
p = Pablo.new
|
92
|
+
p.option :nocolor, :negates => :color
|
93
|
+
p.option :dontshow, :negates => :show
|
94
|
+
p.option :foo
|
95
|
+
p.option :nofoo, :negates => :foo
|
96
|
+
|
97
|
+
p.parse ['--nocolor', '--dontshow', '--foo']
|
98
|
+
|
99
|
+
assert_equal false, p.options[:color]
|
100
|
+
assert_equal false, p.options[:show]
|
101
|
+
assert_equal true, p.options[:foo]
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_option
|
105
|
+
worked = []
|
106
|
+
p = Pablo.new
|
107
|
+
|
108
|
+
p.option :foo do |args, pablo|
|
109
|
+
assert_equal 2, args.length
|
110
|
+
worked << :command
|
111
|
+
end
|
112
|
+
|
113
|
+
p.command :bar do |args, pablo|
|
114
|
+
assert_equal 1, args.length
|
115
|
+
worked << :option
|
116
|
+
end
|
117
|
+
|
118
|
+
p.parse %w{--foo bar baz}
|
119
|
+
assert_equal [:command, :option], worked
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_options
|
123
|
+
worked = []
|
124
|
+
p = Pablo.new
|
125
|
+
|
126
|
+
p.option :goo do |args, pablo|
|
127
|
+
assert_equal 0, args.length
|
128
|
+
worked << :goo
|
129
|
+
end
|
130
|
+
|
131
|
+
p.option :foo do |args, pablo|
|
132
|
+
assert_equal 2, args.length
|
133
|
+
worked << :foo
|
134
|
+
end
|
135
|
+
|
136
|
+
p.command :bar do |args, pablo|
|
137
|
+
assert_equal 1, args.length
|
138
|
+
worked << :bar
|
139
|
+
end
|
140
|
+
|
141
|
+
p.parse %w{--foo bar baz --goo}
|
142
|
+
assert_equal [:goo, :foo, :bar], worked
|
143
|
+
end
|
144
|
+
|
145
|
+
# ------------------ token ------------------
|
146
|
+
|
147
|
+
def test_token
|
148
|
+
worked = []
|
149
|
+
p = Pablo.new
|
150
|
+
|
151
|
+
p.token do |args, pablo|
|
152
|
+
assert_equal 2, args.length
|
153
|
+
worked << :nil
|
154
|
+
end
|
155
|
+
|
156
|
+
p.token 'foo' do |args, pablo|
|
157
|
+
assert_equal 2, args.length
|
158
|
+
worked << :string
|
159
|
+
end
|
160
|
+
|
161
|
+
p.token(/^bar$/) do |args, pablo|
|
162
|
+
assert_equal 1, args.length
|
163
|
+
worked << :rex
|
164
|
+
end
|
165
|
+
|
166
|
+
p.token 'bar', 1 do |args, pablo|
|
167
|
+
assert_equal 1, args.length
|
168
|
+
worked << :pos
|
169
|
+
end
|
170
|
+
|
171
|
+
p.token 'bar', 0 do
|
172
|
+
flunk 'p.token called although specified on position 0'
|
173
|
+
end
|
174
|
+
|
175
|
+
p.command :bar do |args, pablo|
|
176
|
+
assert_equal 0, args.length
|
177
|
+
worked << :sym
|
178
|
+
end
|
179
|
+
|
180
|
+
p.parse %w{foo bar}
|
181
|
+
assert_equal [:nil, :string, :rex, :pos, :sym], worked
|
182
|
+
end
|
183
|
+
|
184
|
+
# ------------------ mixed ------------------
|
185
|
+
|
186
|
+
def test_parser_caches
|
187
|
+
p = Pablo.new
|
188
|
+
p.option :foo
|
189
|
+
p.option :bar
|
190
|
+
p.parse %w{--foo --bar}
|
191
|
+
assert p.options[:foo]
|
192
|
+
assert p.options[:bar]
|
193
|
+
|
194
|
+
p = Pablo.new
|
195
|
+
p.command :foo
|
196
|
+
p.command :bar
|
197
|
+
p.parse %w{foo bar}
|
198
|
+
assert p.commands[:foo]
|
199
|
+
assert_nil p.commands[:bar]
|
200
|
+
|
201
|
+
p = Pablo.new
|
202
|
+
p.option :foo
|
203
|
+
p.option :bar
|
204
|
+
p.parse %w{--foo --bar}
|
205
|
+
assert p.options[:foo]
|
206
|
+
assert p.options[:bar]
|
207
|
+
end
|
208
|
+
|
209
|
+
def test_register
|
210
|
+
p = Pablo.new
|
211
|
+
p.desc "foo"
|
212
|
+
p.longdesc "foo"
|
213
|
+
p.command :foo
|
214
|
+
|
215
|
+
p.desc "bar"
|
216
|
+
p.longdesc "bar"
|
217
|
+
p.option :bar
|
218
|
+
|
219
|
+
p.desc "goo"
|
220
|
+
p.longdesc "goo"
|
221
|
+
p.token :goo
|
222
|
+
|
223
|
+
p.parse ['foo', '--bar', 'goo']
|
224
|
+
assert_equal 3, p.registered.length
|
225
|
+
assert_equal [:foo], p.registered[0].names
|
226
|
+
assert_equal [:bar], p.registered[1].names
|
227
|
+
assert_equal [:goo], p.registered[2].names
|
228
|
+
end
|
229
|
+
|
230
|
+
def test_multiple_names
|
231
|
+
[%w{foo}, %w{bar}].each do |arr|
|
232
|
+
worked = false
|
233
|
+
|
234
|
+
p = Pablo.new
|
235
|
+
p.command :foo, :bar do
|
236
|
+
worked = true
|
237
|
+
end
|
238
|
+
|
239
|
+
p.parse arr
|
240
|
+
assert worked
|
241
|
+
end
|
242
|
+
|
243
|
+
[%w{--foo}, %w{--nobar}].each do |arr|
|
244
|
+
worked = false
|
245
|
+
|
246
|
+
p = Pablo.new
|
247
|
+
p.option :foo, :nobar, :negates => :bar do
|
248
|
+
worked = true
|
249
|
+
end
|
250
|
+
|
251
|
+
p.parse arr
|
252
|
+
assert worked
|
253
|
+
end
|
254
|
+
|
255
|
+
[%w{foo}, %w{bar}].each do |arr|
|
256
|
+
worked = false
|
257
|
+
|
258
|
+
p = Pablo.new
|
259
|
+
p.token :foo, :bar do
|
260
|
+
worked = true
|
261
|
+
end
|
262
|
+
|
263
|
+
p.parse arr
|
264
|
+
assert worked
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
def test_consume_opt
|
269
|
+
[1, /bar/, %w{foo bar}, 'bar'].each do |c|
|
270
|
+
p = Pablo.new
|
271
|
+
p.option :foo, :consume => c
|
272
|
+
p.parse %w{--foo bar}
|
273
|
+
assert_equal 'bar', p.options[:foo]
|
274
|
+
|
275
|
+
p = Pablo.new
|
276
|
+
p.token :foo, :consume => c
|
277
|
+
p.parse %w{bar}
|
278
|
+
assert_equal "bar", p.tokens[:foo]
|
279
|
+
|
280
|
+
p = Pablo.new
|
281
|
+
p.command :foo, :consume => c
|
282
|
+
p.parse %w{foo bar}
|
283
|
+
assert_equal "bar", p.commands[:foo]
|
284
|
+
end
|
285
|
+
|
286
|
+
p = Pablo.new
|
287
|
+
p.option :foo, :consume => 2
|
288
|
+
p.parse %w{--foo bar baz}
|
289
|
+
assert_equal %w{bar baz}, p.options[:foo]
|
290
|
+
|
291
|
+
p = Pablo.new
|
292
|
+
p.token :foo, :consume => 2
|
293
|
+
p.parse %w{foo bar baz}
|
294
|
+
assert_equal %w{foo bar}, p.tokens[:foo]
|
295
|
+
|
296
|
+
p = Pablo.new
|
297
|
+
p.command :foo, :consume => 2
|
298
|
+
p.parse %w{foo bar baz}
|
299
|
+
assert_equal %w{bar baz}, p.commands[:foo]
|
300
|
+
end
|
301
|
+
|
302
|
+
def test_defaults
|
303
|
+
p = Pablo.new
|
304
|
+
p.token :color, /asdf/, :default => :bar
|
305
|
+
p.option :nocolor, :default => :bar, :negates => :color
|
306
|
+
p.command :color, :default => :bar
|
307
|
+
|
308
|
+
p.token :gogo, :default => :bar do
|
309
|
+
p.tokens[:gogo] = :goo
|
310
|
+
end
|
311
|
+
|
312
|
+
p.option :gogo, :default => :bar do
|
313
|
+
p.options[:gogo] = :goo
|
314
|
+
end
|
315
|
+
|
316
|
+
p.command :gogo, :default => :bar do
|
317
|
+
p.commands[:gogo] = :goo
|
318
|
+
end
|
319
|
+
|
320
|
+
p.parse ['gogo', '--gogo']
|
321
|
+
assert_equal :bar, p.tokens[:color]
|
322
|
+
assert_equal :bar, p.options[:nocolor]
|
323
|
+
assert_equal :bar, p.commands[:color]
|
324
|
+
assert_equal :goo, p.commands[:gogo]
|
325
|
+
assert_equal :goo, p.options[:gogo]
|
326
|
+
assert_equal :goo, p.tokens[:gogo]
|
327
|
+
end
|
328
|
+
|
329
|
+
def test_subparsers
|
330
|
+
p = Pablo.new
|
331
|
+
p.command :foo do
|
332
|
+
p.command :bar
|
333
|
+
end
|
334
|
+
|
335
|
+
p.parse %w{foo bar}
|
336
|
+
assert p.commands[:foo]
|
337
|
+
assert p.commands[:bar]
|
338
|
+
|
339
|
+
p = Pablo.new
|
340
|
+
p.option :foo do
|
341
|
+
p.option :bar
|
342
|
+
end
|
343
|
+
|
344
|
+
p.parse %w{--foo -bar}
|
345
|
+
assert p.options[:foo]
|
346
|
+
assert p.options[:bar]
|
347
|
+
|
348
|
+
p = Pablo.new
|
349
|
+
p.token :foo do
|
350
|
+
p.token :bar
|
351
|
+
end
|
352
|
+
|
353
|
+
p.parse %w{foo bar}
|
354
|
+
assert p.tokens[:foo]
|
355
|
+
assert p.tokens[:bar]
|
356
|
+
|
357
|
+
p = Pablo.new
|
358
|
+
p.command :foo do
|
359
|
+
p.command :bar
|
360
|
+
end
|
361
|
+
|
362
|
+
p.parse %w{bar}
|
363
|
+
assert_nil p.commands[:foo]
|
364
|
+
assert_nil p.commands[:bar]
|
365
|
+
|
366
|
+
p = Pablo.new
|
367
|
+
p.option :foo do
|
368
|
+
p.option :bar
|
369
|
+
end
|
370
|
+
|
371
|
+
p.parse %w{bar}
|
372
|
+
assert_nil p.options[:foo]
|
373
|
+
assert_nil p.options[:bar]
|
374
|
+
|
375
|
+
p = Pablo.new
|
376
|
+
p.token :foo, /foo/ do
|
377
|
+
p.token :bar
|
378
|
+
end
|
379
|
+
|
380
|
+
p.parse %w{bar}
|
381
|
+
assert_nil p.tokens[:foo]
|
382
|
+
assert_nil p.tokens[:bar]
|
383
|
+
end
|
384
|
+
|
385
|
+
def test_consume_and_block
|
386
|
+
@worked = []
|
387
|
+
p = Pablo.new
|
388
|
+
p.command :foo, :consume_all => false, :consume => 1 do
|
389
|
+
@worked << :command
|
390
|
+
end
|
391
|
+
|
392
|
+
p.option :bar, :consume => 1 do
|
393
|
+
@worked << :option
|
394
|
+
end
|
395
|
+
|
396
|
+
p.token(:goo, /goo/, :consume => 1) do
|
397
|
+
@worked << :token
|
398
|
+
end
|
399
|
+
|
400
|
+
p.parse %w{foo good --bar bad goo}
|
401
|
+
assert_equal 'good', p.commands[:foo]
|
402
|
+
assert_equal 'bad', p.options[:bar]
|
403
|
+
assert_equal 'goo', p.tokens[:goo]
|
404
|
+
assert_equal [:command, :option, :token], @worked
|
405
|
+
end
|
406
|
+
|
407
|
+
def test_file_functions
|
408
|
+
p = Pablo.new
|
409
|
+
p.token :foo, :directory?
|
410
|
+
p.token :bar, :file?
|
411
|
+
p.token :baz, :exists?
|
412
|
+
|
413
|
+
p.parse [Dir.pwd]
|
414
|
+
assert p.tokens[:foo]
|
415
|
+
assert !p.tokens[:bar]
|
416
|
+
assert p.tokens[:baz]
|
417
|
+
|
418
|
+
p = Pablo.new
|
419
|
+
p.token :foo, :directory?
|
420
|
+
p.token :bar, :file?
|
421
|
+
p.token :baz, :exist?
|
422
|
+
|
423
|
+
p.parse [__FILE__]
|
424
|
+
assert !p.tokens[:foo]
|
425
|
+
assert p.tokens[:bar]
|
426
|
+
assert p.tokens[:baz]
|
427
|
+
|
428
|
+
p = Pablo.new
|
429
|
+
p.token :baz, :exist?
|
430
|
+
|
431
|
+
p.parse [__FILE__ + 'nanana']
|
432
|
+
assert !p.tokens[:baz]
|
433
|
+
end
|
434
|
+
|
435
|
+
def test_position
|
436
|
+
p = Pablo.new
|
437
|
+
p.token :foo, /foo/, 0
|
438
|
+
p.token :bar, /bar/, 0
|
439
|
+
|
440
|
+
p.parse %w{foo bar}
|
441
|
+
assert p.tokens[:foo]
|
442
|
+
assert_nil p.tokens[:bar]
|
443
|
+
|
444
|
+
p = Pablo.new
|
445
|
+
p.token :foo, /foo/, :position => 0
|
446
|
+
p.token :bar, /bar/, :position => 0
|
447
|
+
|
448
|
+
p.parse %w{foo bar}
|
449
|
+
assert p.tokens[:foo]
|
450
|
+
assert_nil p.tokens[:bar]
|
451
|
+
|
452
|
+
p = Pablo.new
|
453
|
+
p.token :foo, /foo/, 0..2
|
454
|
+
p.token :bar, /bar/, 0..2
|
455
|
+
|
456
|
+
p.parse %w{foo foo foo bar}
|
457
|
+
assert p.tokens[:foo]
|
458
|
+
assert_nil p.tokens[:bar]
|
459
|
+
|
460
|
+
p = Pablo.new
|
461
|
+
p.token :foo, /foo/, :position => 0..2
|
462
|
+
p.token :bar, /bar/, :position => 0..2
|
463
|
+
|
464
|
+
p.parse %w{foo foo foo bar}
|
465
|
+
assert p.tokens[:foo]
|
466
|
+
assert_nil p.tokens[:bar]
|
467
|
+
end
|
468
|
+
|
469
|
+
end
|
470
|
+
|