benry-cmdapp 0.1.0 → 1.0.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.
data/test/action_test.rb DELETED
@@ -1,1038 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
-
3
-
4
- require 'oktest'
5
-
6
- require 'benry/cmdapp'
7
- require_relative './shared'
8
-
9
-
10
- Oktest.scope do
11
-
12
-
13
- topic Benry::CmdApp::ActionMetadata do
14
- #include CommonTestingHelper # not work. why?
15
- include ActionMetadataTestingHelper
16
-
17
- class MetadataTestAction < Benry::CmdApp::ActionScope
18
-
19
- @action.("print greeting message")
20
- @option.(:lang, "-l, --lang=<en|fr|it>", "language")
21
- def halo1(user="world", lang: "en")
22
- case lang
23
- when "en" ; puts "Hello, #{user}!"
24
- when "fr" ; puts "Bonjour, #{user}!"
25
- when "it" ; puts "Ciao, #{user}!"
26
- else ; raise "#{lang}: unknown language."
27
- end
28
- end
29
-
30
- @action.("print greeting message")
31
- @option.(:lang, "-l, --lang=<en|fr|it>", "language")
32
- def halo2(user="world", *users, lang: "en")
33
- puts "user=#{user.inspect}, users=#{users.inspect}"
34
- end
35
-
36
- @action.("no arguments")
37
- @option.(:lang, "-l, --lang=<en|fr|it>", "language")
38
- def halo3(lang: "en")
39
- puts "lang=#{lang}"
40
- end
41
-
42
- def args1(aa, bb, xx: nil); end # required arg
43
- def args2(aa, bb=nil, cc=nil, xx: nil); end # optional arg
44
- def args3(aa, bb=nil, cc=nil, *dd, xx: nil); end # variable arg
45
- def args4(xx_or_yy_or_zz); end # xx|yy|zz
46
- def args5(_xx_yy_zz); end # _xx-yy-zz
47
-
48
- end
49
-
50
-
51
- before do
52
- schema = Benry::Cmdopt::Schema.new
53
- schema.add(:lang, "-l, --lang=<en|fr|it>", "language")
54
- @metadata = Benry::CmdApp::ActionMetadata.new("halo1", MetadataTestAction, :halo1, "greeting", schema)
55
- end
56
-
57
-
58
- topic '#hidden?()' do
59
-
60
- class HiddenTestAction < Benry::CmdApp::ActionScope
61
- @action.("public")
62
- def pphidden1(); puts __method__(); end
63
- #
64
- @action.("private")
65
- def pphidden2(); puts __method__(); end
66
- private :pphidden2
67
- #
68
- private
69
- @action.("private")
70
- def pphidden3(); puts __method__(); end
71
- end
72
-
73
- spec "[!kp10p] returns true when action method is private." do
74
- ameta = Benry::CmdApp::INDEX.get_action("pphidden3")
75
- ok {ameta.hidden?} == true
76
- ameta = Benry::CmdApp::INDEX.get_action("pphidden2")
77
- ok {ameta.hidden?} == true
78
- end
79
-
80
- spec "[!nw322] returns false when action method is not private." do
81
- ameta = Benry::CmdApp::INDEX.get_action("pphidden1")
82
- ok {ameta.hidden?} == false
83
- end
84
-
85
- end
86
-
87
-
88
- topic '#importance?()' do
89
-
90
- spec "[!52znh] returns true if `@important == true`." do
91
- ameta = @metadata
92
- ameta.instance_variable_set('@important', true)
93
- ok {ameta.important?} == true
94
- end
95
-
96
- spec "[!rlfac] returns false if `@important == false`." do
97
- ameta = @metadata
98
- ameta.instance_variable_set('@important', false)
99
- ok {ameta.important?} == false
100
- end
101
-
102
- spec "[!j3trl] returns false if `@important == nil`. and action is hidden." do
103
- ameta = @metadata
104
- def ameta.hidden?; true; end
105
- ok {ameta.important?} == false
106
- end
107
-
108
- spec "[!hhef8] returns nil if `@important == nil`." do
109
- ameta = @metadata
110
- ameta.instance_variable_set('@important', nil)
111
- ok {ameta.important?} == nil
112
- end
113
-
114
- end
115
-
116
-
117
- topic '#parse_options()' do
118
-
119
- spec "[!ab3j8] parses argv and returns options." do
120
- args = ["-l", "fr", "Alice"]
121
- opts = @metadata.parse_options(args)
122
- ok {opts} == {:lang => "fr"}
123
- ok {args} == ["Alice"]
124
- args = ["--lang=it", "Bob"]
125
- opts = @metadata.parse_options(args)
126
- ok {opts} == {:lang => "it"}
127
- ok {args} == ["Bob"]
128
- end
129
-
130
- spec "[!56da8] raises InvalidOptionError if option value is invalid." do
131
- args = ["-x", "fr", "Alice"]
132
- pr = proc { @metadata.parse_options(args) }
133
- ok {pr}.raise?(Benry::CmdApp::InvalidOptionError, "-x: Unknown option.")
134
- end
135
-
136
- end
137
-
138
-
139
- topic '#run_action()' do
140
-
141
- spec "[!veass] runs action with args and kwargs." do
142
- args = ["Alice"]; kwargs = {lang: "fr"}
143
- #
144
- sout, serr = capture_sio { @metadata.run_action() }
145
- ok {sout} == "Hello, world!\n"
146
- ok {serr} == ""
147
- #
148
- sout, serr = capture_sio { @metadata.run_action(*args) }
149
- ok {sout} == "Hello, Alice!\n"
150
- ok {serr} == ""
151
- #
152
- sout, serr = capture_sio { @metadata.run_action(**kwargs) }
153
- ok {sout} == "Bonjour, world!\n"
154
- ok {serr} == ""
155
- #
156
- sout, serr = capture_sio { @metadata.run_action(*args, **kwargs) }
157
- ok {sout} == "Bonjour, Alice!\n"
158
- ok {serr} == ""
159
- end
160
-
161
- def _trace_mode(flag, &block)
162
- bkup = $TRACE_MODE
163
- $TRACE_MODE = true
164
- begin
165
- return yield
166
- ensure
167
- $TRACE_MODE = bkup
168
- end
169
- end
170
-
171
- spec "[!tubhv] if $TRACE_MODE is on, prints tracing info." do
172
- args = ["Alice"]; kwargs = {lang: "it"}
173
- sout, serr = _trace_mode(true) do
174
- capture_sio {
175
- @metadata.run_action(*args, **kwargs)
176
- }
177
- end
178
- ok {serr} == ""
179
- ok {sout} == <<"END"
180
- ## enter: halo1
181
- Ciao, Alice!
182
- ## exit: halo1
183
- END
184
- end
185
-
186
- spec "[!zgp14] tracing info is colored when stdout is a tty." do
187
- args = ["Alice"]; kwargs = {lang: "it"}
188
- sout, serr = _trace_mode(true) do
189
- capture_sio(tty: true) {
190
- @metadata.run_action(*args, **kwargs)
191
- }
192
- end
193
- ok {serr} == ""
194
- ok {sout} == <<"END"
195
- \e[33m## enter: halo1\e[0m
196
- Ciao, Alice!
197
- \e[33m## exit: halo1\e[0m
198
- END
199
- end
200
-
201
- end
202
-
203
-
204
- topic '#method_arity()' do
205
-
206
- spec "[!7v4tp] returns min and max number of positional arguments." do
207
- ok {@metadata.method_arity()} == [0, 1]
208
- end
209
-
210
- spec "[!w3rer] max is nil if variable argument exists." do
211
- schema = Benry::Cmdopt::Schema.new
212
- metadata = Benry::CmdApp::ActionMetadata.new("halo2", MetadataTestAction, :halo2, "greeting", schema)
213
- ok {metadata.method_arity()} == [0, nil]
214
- end
215
-
216
- end
217
-
218
-
219
- topic '#validate_method_params()' do
220
-
221
- spec "[!plkhs] returns error message if keyword parameter for option not exist." do
222
- schema = Benry::Cmdopt::Schema.new
223
- schema.add(:foo, "--foo", "foo")
224
- metadata = Benry::CmdApp::ActionMetadata.new("halo1", MetadataTestAction, :halo1, "greeting", schema)
225
- msg = metadata.validate_method_params()
226
- ok {msg} == "Should have keyword parameter 'foo' for '@option.(:foo)', but not."
227
- end
228
-
229
- spec "[!1koi8] returns nil if all keyword parameters for option exist." do
230
- schema = Benry::Cmdopt::Schema.new
231
- schema.add(:lang, "-l, --lang=<lang>", "lang")
232
- metadata = Benry::CmdApp::ActionMetadata.new("halo1", MetadataTestAction, :halo1, "greeting", schema)
233
- msg = metadata.validate_method_params()
234
- ok {msg} == nil
235
- end
236
-
237
- end
238
-
239
-
240
- topic '#help_message()' do
241
-
242
- spec "[!i7siu] returns help message of action." do
243
- schema = new_schema()
244
- msg = without_tty { new_metadata(schema).help_message("testapp") }
245
- ok {uncolorize(msg)} == <<END
246
- testapp halo1 -- greeting
247
-
248
- Usage:
249
- $ testapp halo1 [<options>] [<user>]
250
-
251
- Options:
252
- -l, --lang=<en|fr|it> : language
253
- END
254
- end
255
-
256
- end
257
-
258
-
259
- end
260
-
261
-
262
- topic Benry::CmdApp::ActionWithArgs do
263
- include ActionMetadataTestingHelper
264
-
265
-
266
- topic '#initialize()' do
267
-
268
- spec "[!6jklb] keeps ActionMetadata, args, and kwargs." do
269
- ameta = new_metadata(new_schema())
270
- wrapper = Benry::CmdApp::ActionWithArgs.new(ameta, ["Alice"], {lang: "fr"})
271
- ok {wrapper.action_metadata} == ameta
272
- ok {wrapper.args} == ["Alice"]
273
- ok {wrapper.kwargs} == {lang: "fr"}
274
- end
275
-
276
- end
277
-
278
-
279
- topic '#method_missing()' do
280
-
281
- spec "[!14li3] behaves as ActionMetadata." do
282
- ameta = new_metadata(new_schema())
283
- wrapper = Benry::CmdApp::ActionWithArgs.new(ameta, ["Alice"], {lang: "fr"})
284
- ok {wrapper.name} == ameta.name
285
- ok {wrapper.klass} == ameta.klass
286
- ok {wrapper.schema} == ameta.schema
287
- ok {wrapper.method_arity()} == ameta.method_arity()
288
- end
289
-
290
- end
291
-
292
-
293
- topic '#run_action()' do
294
-
295
- class ActionWithArgsTest < Benry::CmdApp::ActionScope
296
- @action.("hello")
297
- @option.(:lang, "-l <lang>", "language")
298
- @option.(:repeat, "-r <N>", "repeat <N> times")
299
- def hellowithargs(user1="alice", user2="bob", lang: nil, repeat: nil)
300
- puts "user1=#{user1}, user2=#{user2}, lang=#{lang.inspect}, repeat=#{repeat.inspect}"
301
- end
302
- end
303
-
304
- spec "[!fl26i] invokes action with args and kwargs." do
305
- ameta = Benry::CmdApp::INDEX.get_action("hellowithargs")
306
- #
307
- wrapper = Benry::CmdApp::ActionWithArgs.new(ameta, ["bill"], {repeat: 3})
308
- sout, serr = capture_sio() { wrapper.run_action() }
309
- ok {serr} == ""
310
- ok {sout} == "user1=bill, user2=bob, lang=nil, repeat=3\n"
311
- #
312
- wrapper = Benry::CmdApp::ActionWithArgs.new(ameta, ["bill"], nil)
313
- sout, serr = capture_sio() { wrapper.run_action() }
314
- ok {serr} == ""
315
- ok {sout} == "user1=bill, user2=bob, lang=nil, repeat=nil\n"
316
- #
317
- wrapper = Benry::CmdApp::ActionWithArgs.new(ameta, nil, {repeat: 3})
318
- sout, serr = capture_sio() { wrapper.run_action() }
319
- ok {serr} == ""
320
- ok {sout} == "user1=alice, user2=bob, lang=nil, repeat=3\n"
321
- end
322
-
323
- end
324
-
325
-
326
- end
327
-
328
-
329
- topic Benry::CmdApp::ActionScope do
330
-
331
-
332
- class InvokeTestAction < Benry::CmdApp::ActionScope
333
- prefix "test3:foo"
334
- #
335
- @action.("invoke once")
336
- @option.(:lang, "-l, --lang=<en|fr>", "language")
337
- def invoke1(user="world", lang: "en")
338
- puts(lang == "fr" ? "Bonjour, #{user}!" : "Hello, #{user}!")
339
- end
340
- #
341
- @action.("invoke twice")
342
- @option.(:lang, "-l, --lang=<en|fr>", "language")
343
- def invoke2(user="world", lang: "en")
344
- puts(lang == "fr" ? "Bonjour, #{user}!" : "Hello, #{user}!")
345
- end
346
- #
347
- @action.("invoke more")
348
- @option.(:lang, "-l, --lang=<en|fr>", "language")
349
- def invoke3(user="world", lang: "en")
350
- puts(lang == "fr" ? "Bonjour, #{user}!" : "Hello, #{user}!")
351
- end
352
- end
353
-
354
- class LoopedActionTest < Benry::CmdApp::ActionScope
355
- @action.("test")
356
- def loop1()
357
- run_action_once("loop2")
358
- end
359
- @action.("test")
360
- def loop2()
361
- run_action_once("loop3")
362
- end
363
- @action.("test")
364
- def loop3()
365
- run_action_once("loop1")
366
- end
367
- end
368
-
369
- before do
370
- @action = InvokeTestAction.new()
371
- Benry::CmdApp::INDEX.instance_variable_get('@done').clear()
372
- end
373
-
374
-
375
- topic '#run_action_once()' do
376
-
377
- spec "[!oh8dc] don't invoke action if already invoked." do
378
- sout, serr = capture_sio() do
379
- @action.run_action_once("test3:foo:invoke2", "Alice", lang: "fr")
380
- end
381
- ok {sout} == "Bonjour, Alice!\n"
382
- sout, serr = capture_sio() do
383
- @action.run_action_once("test3:foo:invoke2", "Alice", lang: "fr")
384
- end
385
- ok {sout} == ""
386
- ok {serr} == ""
387
- end
388
-
389
- end
390
-
391
-
392
- topic '#run_action!()' do
393
-
394
- spec "[!2yrc2] invokes action even if already invoked." do
395
- sout, serr = capture_sio() do
396
- @action.run_action!("test3:foo:invoke3", "Alice", lang: "fr")
397
- end
398
- ok {sout} == "Bonjour, Alice!\n"
399
- sout, serr = capture_sio() do
400
- @action.run_action!("test3:foo:invoke3", "Alice", lang: "fr")
401
- end
402
- ok {sout} == "Bonjour, Alice!\n"
403
- sout, serr = capture_sio() do
404
- @action.run_action!("test3:foo:invoke3", "Alice", lang: "en")
405
- end
406
- ok {sout} == "Hello, Alice!\n"
407
- end
408
-
409
- end
410
-
411
-
412
- topic '#__run_action()' do
413
-
414
- def __run_action(action_name, once, args, kwargs)
415
- @action.__send__(:__run_action, action_name, once, args, kwargs)
416
- end
417
-
418
- def __run_loop(action_name, once, args, kwargs)
419
- action = LoopedActionTest.new()
420
- action.__send__(:__run_action, action_name, once, args, kwargs)
421
- end
422
-
423
- spec "[!lbp9r] invokes action name with prefix if prefix defined." do
424
- sout, serr = capture_sio() do
425
- @action.run_action_once("invoke2", "Alice", lang: "fr")
426
- end
427
- ok {sout} == "Bonjour, Alice!\n"
428
- end
429
-
430
- spec "[!7vszf] raises error if action specified not found." do
431
- pr = proc { __run_action("loop9", nil, ["Alice"], {}) }
432
- ok {pr}.raise?(Benry::CmdApp::ActionNotFoundError, "loop9: Action not found.")
433
- end
434
-
435
- spec "[!u8mit] raises error if action flow is looped." do
436
- pr = proc { __run_loop("loop1", nil, [], {}) }
437
- ok {pr}.raise?(Benry::CmdApp::LoopedActionError, "loop1: Action loop detected.")
438
- end
439
-
440
- spec "[!vhdo9] don't invoke action twice if 'once' arg is true." do
441
- sout, serr = capture_sio() do
442
- __run_action("test3:foo:invoke2", true, ["Alice"], {lang: "fr"})
443
- end
444
- ok {sout} == "Bonjour, Alice!\n"
445
- sout, serr = capture_sio() do
446
- __run_action("test3:foo:invoke2", true, ["Alice"], {lang: "fr"})
447
- end
448
- ok {sout} == ""
449
- ok {serr} == ""
450
- end
451
-
452
- spec "[!r8fbn] invokes action." do
453
- sout, serr = capture_sio() do
454
- __run_action("test3:foo:invoke1", false, ["Alice"], {lang: "fr"})
455
- end
456
- ok {sout} == "Bonjour, Alice!\n"
457
- end
458
-
459
- end
460
-
461
-
462
- topic '.prefix()' do
463
-
464
- spec "[!1gwyv] converts symbol into string." do
465
- class PrefixTest1 < Benry::CmdApp::ActionScope
466
- prefix :foo
467
- end
468
- prefix = PrefixTest1.instance_variable_get('@__prefix__')
469
- ok {prefix} == "foo:"
470
- end
471
-
472
- spec "[!pz46w] error if prefix contains extra '_'." do
473
- pr = proc do
474
- class PrefixTest2 < Benry::CmdApp::ActionScope
475
- prefix "foo_bar"
476
- end
477
- end
478
- ok {pr}.raise?(Benry::CmdApp::ActionDefError,
479
- "foo_bar: Invalid prefix name (please use ':' or '-' instead of '_' as word separator).")
480
- end
481
-
482
- spec "[!9pu01] adds ':' at end of prefix name if prefix not end with ':'." do
483
- class PrefixTest3 < Benry::CmdApp::ActionScope
484
- prefix "foo:bar"
485
- end
486
- prefix = PrefixTest3.instance_variable_get('@__prefix__')
487
- ok {prefix} == "foo:bar:"
488
- end
489
-
490
- end
491
-
492
-
493
- topic '.inherited()' do
494
-
495
- spec "[!f826w] registers all subclasses into 'ActionScope::SUBCLASSES'." do
496
- class InheritedTest0a < Benry::CmdApp::ActionScope
497
- end
498
- class InheritedTest0b < Benry::CmdApp::ActionScope
499
- end
500
- ok {Benry::CmdApp::ActionScope::SUBCLASSES}.include?(InheritedTest0a)
501
- ok {Benry::CmdApp::ActionScope::SUBCLASSES}.include?(InheritedTest0b)
502
- end
503
-
504
- spec "[!2imrb] sets class instance variables in subclass." do
505
- class InheritedTest1 < Benry::CmdApp::ActionScope
506
- end
507
- ivars = InheritedTest1.instance_variables().sort()
508
- ok {ivars} == [:@__action__, :@__aliasof__, :@__default__, :@__option__, :@__prefix__, :@action, :@copy_options, :@option]
509
- end
510
-
511
- spec "[!1qv12] @action is a Proc object and saves args." do
512
- class InheritedTest2 < Benry::CmdApp::ActionScope
513
- @action.("description", detail: "xxx", postamble: "yyy", important: true, tag: "zzz")
514
- end
515
- x = InheritedTest2.instance_variable_get('@__action__')
516
- ok {x} == ["description", {detail: "xxx", postamble: "yyy", important: true, tag: "zzz"}]
517
- end
518
-
519
- spec "[!33ma7] @option is a Proc object and saves args." do
520
- class InheritedTest3 < Benry::CmdApp::ActionScope
521
- @action.("description", detail: "xxx", postamble: "yyy")
522
- @option.(:xx, "-x, --xxx=<N>", "desc 1", type: Integer, rexp: /\A\d+\z/, enum: [2,4,8], range: (2..8))
523
- @option.(:yy, "-y, --yyy[=<on|off>]", "desc 2", type: TrueClass, value: false)
524
- end
525
- x = InheritedTest3.instance_variable_get('@__option__')
526
- ok {x}.is_a?(Benry::CmdOpt::Schema)
527
- items = x.each.to_a()
528
- ok {items.length} == 2
529
- ok {items[0].key} == :xx
530
- ok {items[0].optdef} == "-x, --xxx=<N>"
531
- ok {items[0].desc} == "desc 1"
532
- ok {items[0].type} == Integer
533
- ok {items[0].rexp} == /\A\d+\z/
534
- ok {items[0].enum} == [2, 4, 8]
535
- ok {items[0].range} == (2..8)
536
- ok {items[0].value} == nil
537
- ok {items[1].key} == :yy
538
- ok {items[1].optdef} == "-y, --yyy[=<on|off>]"
539
- ok {items[1].desc} == "desc 2"
540
- ok {items[1].type} == TrueClass
541
- ok {items[1].rexp} == nil
542
- ok {items[1].enum} == nil
543
- ok {items[1].range} == nil
544
- ok {items[1].value} == false
545
- end
546
-
547
- spec "[!gxybo] '@option.()' raises error when '@action.()' not called." do
548
- pr = proc do
549
- class InheritedTest4 < Benry::CmdApp::ActionScope
550
- @option.(:xx, "-x, --xxx=<N>", "desc 1")
551
- end
552
- end
553
- ok {pr}.raise?(Benry::CmdApp::OptionDefError,
554
- "@option.(:xx): `@action.()` Required but not called.")
555
- end
556
-
557
- spec "[!ga6zh] '@option.()' raises error when invalid option info specified." do
558
- pr = proc do
559
- class InheritedTest20 < Benry::CmdApp::ActionScope
560
- @action.("test")
561
- @option.(:xx, "-x, --xxx=<N>", "desc 1", range: (2..8))
562
- def hello(xx: nil)
563
- end
564
- end
565
- end
566
- ok {pr}.raise?(Benry::CmdApp::OptionDefError,
567
- "2..8: Range value should be String, but not.")
568
- end
569
-
570
- spec "[!yrkxn] @copy_options is a Proc object and copies options from other action." do
571
- class InheritedTest5 < Benry::CmdApp::ActionScope
572
- @action.("copy src")
573
- @option.(:xxx, "-x, --xxx=<arg>", "xxx #1")
574
- def optcopy1(xxx: nil)
575
- end
576
- #
577
- @action.("copy dst")
578
- @copy_options.("optcopy1")
579
- @option.(:yyy, "-y, --yyy=<on|off>", "yyy #2", type=TrueClass)
580
- end
581
- x = InheritedTest5.instance_variable_get('@__option__')
582
- ok {x}.is_a?(Benry::CmdOpt::Schema)
583
- items = x.each.to_a()
584
- ok {items.length} == 2
585
- ok {items[0].key} == :xxx
586
- ok {items[0].short} == "x"
587
- ok {items[0].long} == "xxx"
588
- ok {items[1].key} == :yyy
589
- ok {items[1].short} == "y"
590
- ok {items[1].long} == "yyy"
591
- end
592
-
593
- spec "[!mhhn2] '@copy_options.()' raises error when action not found." do
594
- pr = proc do
595
- class InheritedTest6 < Benry::CmdApp::ActionScope
596
- @action.("copy")
597
- @copy_options.("optcopy99")
598
- def copytest2(yyy: nil)
599
- end
600
- end
601
- end
602
- ok {pr}.raise?(Benry::CmdApp::OptionDefError,
603
- "@copy_options.(\"optcopy99\"): Action not found.")
604
- end
605
-
606
- end
607
-
608
-
609
- topic '.method_added()' do
610
-
611
- def defined_actions()
612
- actions = Benry::CmdApp::INDEX.instance_variable_get('@actions')
613
- action_names = actions.keys()
614
- yield
615
- new_names = actions.keys() - action_names
616
- metadata = new_names.length > 0 ? Benry::CmdApp::INDEX.get_action(new_names[0]) : nil
617
- return new_names, metadata
618
- end
619
-
620
- spec "[!idh1j] do nothing if '@__action__' is nil." do
621
- new_names, x = defined_actions() do
622
- class Added1Test < Benry::CmdApp::ActionScope
623
- prefix "added1"
624
- def hello1(); end
625
- end
626
- end
627
- ok {new_names} == []
628
- ok {x} == nil
629
- end
630
-
631
- spec "[!ernnb] clears both '@__action__' and '@__option__'." do
632
- new_names, x = defined_actions() do
633
- class Added2Test < Benry::CmdApp::ActionScope
634
- @action.("test", detail: "XXX", postamble: "YYY")
635
- @option.(:foo, "--foo", "foo")
636
- end
637
- ok {Added2Test.instance_variable_get('@__action__')} != nil
638
- ok {Added2Test.instance_variable_get('@__option__')} != nil
639
- Added2Test.class_eval do
640
- def hello2(foo: nil); end
641
- end
642
- ok {Added2Test.instance_variable_get('@__action__')} == nil
643
- ok {Added2Test.instance_variable_get('@__option__')} == nil
644
- end
645
- end
646
-
647
- spec "[!n8tem] creates ActionMetadata object if '@__action__' is not nil." do
648
- new_names, x = defined_actions() do
649
- class Added3Test < Benry::CmdApp::ActionScope
650
- prefix "added3"
651
- @action.("test", detail: "XXX", postamble: "YYY")
652
- def hello3(); end
653
- end
654
- end
655
- ok {new_names} == ["added3:hello3"]
656
- ok {x}.is_a?(Benry::CmdApp::ActionMetadata)
657
- ok {x.name} == "added3:hello3"
658
- ok {x.klass} == Added3Test
659
- ok {x.method} == :hello3
660
- ok {x.hidden?} == false
661
- ok {x.detail} == "XXX"
662
- ok {x.postamble} == "YYY"
663
- end
664
-
665
- spec "[!4pbsc] raises error if keyword param for option not exist in method." do
666
- pr = proc do
667
- class Added4Test < Benry::CmdApp::ActionScope
668
- prefix "added4"
669
- @action.("test")
670
- @option.(:flag, "--flag=<on|off>", nil, type: TrueClass)
671
- def hello4(xx: nil); end
672
- end
673
- end
674
- ok {pr}.raise?(Benry::CmdApp::ActionDefError,
675
- "def hello4(): Should have keyword parameter 'flag' for '@option.(:flag)', but not.")
676
- end
677
-
678
- spec "[!t8vbf] raises error if action name duplicated." do
679
- pr = proc do
680
- class Added5Test < Benry::CmdApp::ActionScope
681
- prefix "added5"
682
- @action.("test")
683
- def hello5(xx: nil); end
684
- @action.("test")
685
- def hello5(xx: nil); end
686
- end
687
- end
688
- ok {pr}.raise?(Benry::CmdApp::ActionDefError,
689
- "def hello5(): Action 'added5:hello5' already exist.")
690
- end
691
-
692
- case_when '[!5e5o0] when method name is same as default action name...' do
693
-
694
- spec "[!myj3p] uses prefix name (expect last char ':') as action name." do
695
- new_names, x = defined_actions() do
696
- class Added6Test < Benry::CmdApp::ActionScope
697
- prefix "added6", action: :hello6
698
- @action.("test")
699
- def hello6(); end
700
- end
701
- end
702
- ok {new_names} == ["added6"]
703
- ok {x.klass} == Added6Test
704
- ok {x.method} == :hello6
705
- end
706
-
707
- spec "[!j5oto] clears '@__default__'." do
708
- class ClearDefaultTest1 < Benry::CmdApp::ActionScope
709
- prefix "cleardefault1", action: :test2_ # symbol
710
- @__default__ != nil or
711
- raise MiniTest::Assertion, "@__default__ should NOT be nil"
712
- #
713
- @action.("test")
714
- def test1_(); end
715
- @__default__ != nil or
716
- raise MiniTest::Assertion, "@__default__ should NOT be nil"
717
- #
718
- @action.("test")
719
- def test2_(); end
720
- @__default__ == nil or
721
- raise MiniTest::Assertion, "@__default__ should be nil"
722
- end
723
- end
724
-
725
- end
726
-
727
- case_else '[!agpwh] else...' do
728
-
729
- spec "[!3icc4] uses method name as action name." do
730
- new_names, x = defined_actions() do
731
- class Added7Test < Benry::CmdApp::ActionScope
732
- @action.("test")
733
- def hello7xx(); end
734
- end
735
- end
736
- ok {new_names} == ["hello7xx"]
737
- ok {x.klass} == Added7Test
738
- ok {x.method} == :hello7xx
739
- end
740
-
741
- spec "[!c643b] converts action name 'aa_bb_cc_' into 'aa_bb_cc'." do
742
- new_names, x = defined_actions() do
743
- class Added8Test < Benry::CmdApp::ActionScope
744
- @action.("test")
745
- def hello8xx_(); end
746
- end
747
- end
748
- ok {new_names} == ["hello8xx"]
749
- ok {x.klass} == Added8Test
750
- ok {x.method} == :hello8xx_
751
- end
752
-
753
- spec "[!3fkb3] converts action name 'aa__bb__cc' into 'aa:bb:cc'." do
754
- new_names, x = defined_actions() do
755
- class Added9Test < Benry::CmdApp::ActionScope
756
- @action.("test")
757
- def hello9xx__yy__zz(); end
758
- end
759
- end
760
- ok {new_names} == ["hello9xx:yy:zz"]
761
- ok {x.klass} == Added9Test
762
- ok {x.method} == :hello9xx__yy__zz
763
- end
764
-
765
- spec "[!o9s9h] converts action name 'aa_bb:_cc_dd' into 'aa-bb:_cc-dd'." do
766
- new_names, x = defined_actions() do
767
- class Added10Test < Benry::CmdApp::ActionScope
768
- @action.("test")
769
- def _hello10xx_yy_zz(); end
770
- end
771
- end
772
- ok {new_names} == ["_hello10xx-yy-zz"]
773
- ok {x.klass} == Added10Test
774
- ok {x.method} == :_hello10xx_yy_zz
775
- end
776
-
777
- spec "[!8hlni] when action name is same as default name, uses prefix as action name." do
778
- new_names, x = defined_actions() do
779
- class Added11Test < Benry::CmdApp::ActionScope
780
- prefix "added11", action: "hello11"
781
- @action.("test")
782
- def hello11(); end
783
- end
784
- end
785
- ok {new_names} == ["added11"]
786
- ok {x.klass} == Added11Test
787
- ok {x.method} == :hello11
788
- end
789
-
790
- spec "[!q8oxi] clears '@__default__' when default name matched to action name." do
791
- class ClearDefaultTest2 < Benry::CmdApp::ActionScope
792
- prefix "cleardefault2", action: "test2" # string
793
- @__default__ != nil or
794
- raise MiniTest::Assertion, "@__default__ should NOT be nil"
795
- #
796
- @action.("test")
797
- def test1_(); end
798
- @__default__ != nil or
799
- raise MiniTest::Assertion, "@__default__ should NOT be nil"
800
- #
801
- @action.("test")
802
- def test2_(); end
803
- @__default__ == nil or
804
- raise MiniTest::Assertion, "@__default__ should be nil"
805
- end
806
- end
807
-
808
- spec "[!xfent] when prefix is provided, adds it to action name." do
809
- new_names, x = defined_actions() do
810
- class Added12Test < Benry::CmdApp::ActionScope
811
- prefix "added12"
812
- @action.("test")
813
- def hello12(); end
814
- end
815
- end
816
- ok {new_names} == ["added12:hello12"]
817
- ok {x.klass} == Added12Test
818
- ok {x.method} == :hello12
819
- end
820
-
821
- end
822
-
823
- spec "[!jpzbi] defines same name alias of action as prefix." do
824
- ## when symbol
825
- class AliasOfTest1 < Benry::CmdApp::ActionScope
826
- prefix "blabla1", alias_of: :bla1 # symbol
827
- @action.("test")
828
- def bla1(); end
829
- end
830
- ok {Benry::CmdApp::INDEX.get_alias("blabla1")} != nil
831
- ok {Benry::CmdApp::INDEX.get_alias("blabla1").action_name} == "blabla1:bla1"
832
- ## when string
833
- class AliasOfTest2 < Benry::CmdApp::ActionScope
834
- prefix "bla:bla2", alias_of: "blala" # string
835
- @action.("test")
836
- def blala(); end
837
- end
838
- ok {Benry::CmdApp::INDEX.get_alias("bla:bla2")} != nil
839
- ok {Benry::CmdApp::INDEX.get_alias("bla:bla2").action_name} == "bla:bla2:blala"
840
- end
841
-
842
- spec "[!tvjb0] clears '@__aliasof__' only when alias created." do
843
- class AliasOfTest3 < Benry::CmdApp::ActionScope
844
- prefix "bla:bla3", alias_of: "bla3b" # string
845
- @__aliasof__ != nil or
846
- raise MiniTest::Assertion, "@__aliasof__ should NOT be nil"
847
- #
848
- @action.("test")
849
- def bla3a(); end
850
- @__aliasof__ != nil or
851
- raise MiniTest::Assertion, "@__aliasof__ should NOT be nil"
852
- #
853
- @action.("test")
854
- def bla3b(); end
855
- @__aliasof__ == nil or
856
- raise MiniTest::Assertion, "@__aliasof__ should be nil"
857
- end
858
- begin
859
- ok {AliasOfTest3.instance_variable_get('@__aliasof__')} == nil
860
- ensure
861
- AliasOfTest3.class_eval do
862
- @__aliasof__ = nil
863
- end
864
- end
865
- end
866
-
867
- spec "[!997gs] not raise error when action not found." do
868
- pr = proc do
869
- class AliasOfTest4 < Benry::CmdApp::ActionScope
870
- prefix "blabla4", alias_of: :bla99 # action not exist
871
- @action.("test")
872
- def bla3(); end
873
- end
874
- end
875
- begin
876
- ok {pr}.NOT.raise?(Exception)
877
- ensure
878
- AliasOfTest4.class_eval { @__aliasof__ = nil }
879
- end
880
- end
881
-
882
- spec "[!349nr] raises error when same name action or alias with prefix already exists." do
883
- pr = proc do
884
- class AliasOfTest5a < Benry::CmdApp::ActionScope
885
- @action.("test")
886
- def bla5(); end # define 'bla5' action
887
- end
888
- class AliasOfTest5b < Benry::CmdApp::ActionScope
889
- prefix "bla5", alias_of: :blala # define 'bla5' action, too
890
- @action.("test")
891
- def blala(); end
892
- end
893
- end
894
- begin
895
- ok {pr}.raise?(Benry::CmdApp::AliasDefError,
896
- 'action_alias("bla5", "bla5:blala"): Not allowed to define same name alias as existing action.')
897
- ensure
898
- AliasOfTest5b.class_eval { @__aliasof__ = nil }
899
- end
900
- end
901
-
902
- end
903
-
904
-
905
- end
906
-
907
-
908
- topic Benry::CmdApp::BuiltInAction do
909
- include CommonTestingHelper
910
-
911
- before do
912
- @config = Benry::CmdApp::Config.new("test app", "1.0.0")
913
- @config.app_name = "TestApp"
914
- @config.app_command = "testapp"
915
- @config.default_action = nil
916
- @app = Benry::CmdApp::Application.new(@config)
917
- end
918
-
919
-
920
- topic '#help()' do
921
-
922
- spec "[!jfgsy] prints help message of action if action name specified." do
923
- sout, serr = capture_sio { @app.run("help", "help") }
924
- ok {serr} == ""
925
- ok {uncolorize(sout)} == <<"END"
926
- testapp help -- print help message (of action)
927
-
928
- Usage:
929
- $ testapp help [<options>] [<action>]
930
-
931
- Options:
932
- -a, --all : show private (hidden) options, too
933
- END
934
- end
935
-
936
- spec "[!fhpjg] prints help message of command if action name not specified." do
937
- sout, serr = capture_sio { @app.run("help") }
938
- ok {serr} == ""
939
- ok {sout}.start_with?(<<"END")
940
- TestApp (1.0.0) -- test app
941
-
942
- Usage:
943
- $ testapp [<options>] [<action> [<arguments>...]]
944
-
945
- Options:
946
- -h, --help : print help message
947
- -V, --version : print version
948
-
949
- Actions:
950
- END
951
- end
952
-
953
- spec "[!6g7jh] prints colorized help message when color mode is on." do
954
- sout, serr = capture_sio(tty: true) { @app.run("help") }
955
- ok {serr} == ""
956
- ok {sout}.start_with?(<<"END")
957
- \e[1mTestApp\e[0m (1.0.0) -- test app
958
-
959
- \e[34mUsage:\e[0m
960
- $ \e[1mtestapp\e[0m [<options>] [<action> [<arguments>...]]
961
-
962
- \e[34mOptions:\e[0m
963
- \e[1m-h, --help \e[0m : print help message
964
- \e[1m-V, --version \e[0m : print version
965
-
966
- \e[34mActions:\e[0m
967
- END
968
- end
969
-
970
- spec "[!ihr5u] prints non-colorized help message when color mode is off." do
971
- sout, serr = capture_sio(tty: false) { @app.run("help") }
972
- ok {serr} == ""
973
- ok {sout}.start_with?(<<"END")
974
- TestApp (1.0.0) -- test app
975
-
976
- Usage:
977
- $ testapp [<options>] [<action> [<arguments>...]]
978
-
979
- Options:
980
- -h, --help : print help message
981
- -V, --version : print version
982
-
983
- Actions:
984
- END
985
- end
986
-
987
- end
988
-
989
-
990
- end
991
-
992
-
993
- topic Benry::CmdApp::Alias do
994
-
995
- class Alias2Test < Benry::CmdApp::ActionScope
996
- prefix "alias2"
997
- #
998
- @action.("alias test")
999
- def a1(); end
1000
- #
1001
- @action.("alias test", important: true)
1002
- def a2(); end
1003
- #
1004
- @action.("alias test", important: false)
1005
- def a3(); end
1006
- #
1007
- private
1008
- @action.("alias test")
1009
- def a4(); end
1010
- end
1011
-
1012
-
1013
- topic '#important?()' do
1014
-
1015
- spec "[!5juwq] returns true if `@important == true`." do
1016
- ali = Benry::CmdApp::Alias.new("a2-1", "alias2:a1", important: true)
1017
- ok {ali.important?} == true
1018
- end
1019
-
1020
- spec "[!1gnbc] returns false if `@important == false`." do
1021
- ali = Benry::CmdApp::Alias.new("a2-2", "alias2:a1", important: false)
1022
- ok {ali.important?} == false
1023
- end
1024
-
1025
- spec "[!h3nm3] returns true or false according to action object if `@important == nil`." do
1026
- ok {Benry::CmdApp::Alias.new("ali1", "alias2:a1").important?} == nil
1027
- ok {Benry::CmdApp::Alias.new("ali1", "alias2:a2").important?} == true
1028
- ok {Benry::CmdApp::Alias.new("ali1", "alias2:a3").important?} == false
1029
- ok {Benry::CmdApp::Alias.new("ali1", "alias2:a4").important?} == false
1030
- end
1031
-
1032
- end
1033
-
1034
-
1035
- end
1036
-
1037
-
1038
- end