benry-cmdapp 0.2.0 → 1.1.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.
@@ -0,0 +1,1219 @@
1
+ # -*- coding: utf-8 -*-
2
+ # frozen_string_literal: true
3
+
4
+
5
+ require_relative 'shared'
6
+
7
+
8
+
9
+ class ScopeTestAction < Benry::CmdApp::Action
10
+
11
+ @action.("test")
12
+ def scope9392()
13
+ end
14
+
15
+ end
16
+
17
+
18
+ class OverrideTestAction1 < Benry::CmdApp::Action
19
+ def foo1__bar1()
20
+ end
21
+ end
22
+
23
+ class OverrideTestAction2 < OverrideTestAction1
24
+ #category "foo1:"
25
+ #@action.("foo1")
26
+ #def bar1()
27
+ #end
28
+ end
29
+
30
+
31
+ Oktest.scope do
32
+
33
+
34
+ topic Benry::CmdApp::ActionScope do
35
+
36
+ before do
37
+ @config = Benry::CmdApp::Config.new("test app", "1.2.3",
38
+ app_name: "TestApp", app_command: "testapp",
39
+ option_verbose: true, option_quiet: true,
40
+ option_color: true, #option_debug: true,
41
+ option_trace: true)
42
+ end
43
+
44
+
45
+ topic '#__clear_recursive_reference()' do
46
+
47
+ spec "[!i68z0] clears instance var which refers context object." do
48
+ scope = Benry::CmdApp::ActionScope.new(@config)
49
+ ctx = scope.instance_eval { @__context__ }
50
+ ok {ctx} != nil
51
+ scope.__clear_recursive_reference()
52
+ ctx = scope.instance_eval { @__context__ }
53
+ ok {ctx} == nil
54
+ end
55
+
56
+ end
57
+
58
+
59
+ topic '.inherited()' do
60
+
61
+ spec "[!8cck9] sets Proc object to `@action` in subclass." do
62
+ x = ScopeTestAction.class_eval { @action }
63
+ ok {x}.is_a?(Proc)
64
+ ok {x}.lambda?
65
+ end
66
+
67
+ spec "[!r07i7] `@action.()` raises DefinitionError if called consectively." do
68
+ pr = proc do
69
+ ScopeTestAction.class_eval do
70
+ @action.("foo")
71
+ @action.("bar")
72
+ def dummy4922()
73
+ end
74
+ end
75
+ end
76
+ ok {pr}.raise?(Benry::CmdApp::DefinitionError,
77
+ "`@action.()` called without method definition (please define method for this action).")
78
+ end
79
+
80
+ spec "[!34psw] `@action.()` stores arguments into `@__actiondef__`." do
81
+ x = nil
82
+ ScopeTestAction.class_eval do
83
+ @__actiondef__ = nil
84
+ #
85
+ @action.("test")
86
+ x = @__actiondef__
87
+ def dummy2321()
88
+ end
89
+ end
90
+ ok {x}.is_a?(Array).length(3)
91
+ ok {x[0]} == "test"
92
+ ok {x[1]}.is_a?(Benry::CmdApp::ACTION_OPTION_SCHEMA_CLASS)
93
+ ok {x[2]} == {:usage=>nil, :detail=>nil, :description=>nil, :postamble=>nil, :tag=>nil, :important=>nil, :hidden=>nil}
94
+ end
95
+
96
+ spec "[!en6n0] sets Proc object to `@option` in subclass." do
97
+ x = ScopeTestAction.class_eval { @option }
98
+ ok {x}.is_a?(Proc)
99
+ ok {x}.lambda?
100
+ end
101
+
102
+ spec "[!68hf8] raises DefinitionError if `@option.()` called without `@action.()`." do
103
+ pr = proc do
104
+ ScopeTestAction.class_eval do
105
+ @__actiondef__ = nil
106
+ @option.(:help, "-", "help")
107
+ end
108
+ end
109
+ ok {pr}.raise?(Benry::CmdApp::DefinitionError,
110
+ "`@option.()` called without `@action.()`.")
111
+ end
112
+
113
+ spec "[!2p98r] `@option.()` stores arguments into option schema object." do
114
+ tuple = nil
115
+ ScopeTestAction.class_eval do
116
+ @action.("foobar")
117
+ @option.(:lang, "-l <lang>", "language", detail: "blabla", hidden: true) {|val| val }
118
+ @option.(:color, "--color[=<on|off>]", "color mode", type: TrueClass)
119
+ @option.(:ints, "-n <N>", "integers", multiple: true, type: Integer)
120
+ tuple = @__actiondef__
121
+ def s2055(help: false, lang: nil, color: nil, ints: nil)
122
+ end
123
+ end
124
+ schema = tuple[1]
125
+ ok {schema}.is_a?(Benry::CmdApp::ACTION_OPTION_SCHEMA_CLASS)
126
+ #
127
+ x = schema.get(:lang)
128
+ ok {x.key} == :lang
129
+ ok {x.short} == "l"
130
+ ok {x.long} == nil
131
+ ok {x.desc} == "language"
132
+ ok {x.type} == nil
133
+ ok {x.detail} == "blabla"
134
+ ok {x.multiple?} == false
135
+ ok {x.hidden?} == true
136
+ ok {x.callback}.is_a?(Proc)
137
+ #
138
+ x = schema.get(:color)
139
+ ok {x.key} == :color
140
+ ok {x.short} == nil
141
+ ok {x.long} == "color"
142
+ ok {x.desc} == "color mode"
143
+ ok {x.type} == TrueClass
144
+ ok {x.detail} == nil
145
+ ok {x.multiple?} == false
146
+ ok {x.hidden?} == false
147
+ ok {x.callback} == nil
148
+ #
149
+ x = schema.get(:ints)
150
+ ok {x.key} == :ints
151
+ ok {x.short} == "n"
152
+ ok {x.long} == nil
153
+ ok {x.multiple?} == true
154
+ end
155
+
156
+ spec "[!aiwns] `@copy_options.()` copies options from other action." do
157
+ MyAction.class_eval do
158
+ @action.("hello 1291")
159
+ @option.(:lang, "-l <lang>", "language")
160
+ @option.(:color, "--color[=<on|off>]", "color mode", type: TrueClass)
161
+ @option.(:debug, "-D", "debug mode")
162
+ @option.(:trace, "-T", "trace mode")
163
+ @option.(:indent, "-i[<N>]", "indent", type: Integer)
164
+ def hello1291(lang: nil, color: false, debug: false, trace: false, indent: 0)
165
+ end
166
+ #
167
+ @action.("hello 3942")
168
+ @copy_options.("hello1291", except: [:debug, :trace])
169
+ @option.(:silent, "--silent", "silent mode")
170
+ def hello3942(lang: "en", color: false, indent: 0, silent: false)
171
+ end
172
+ end
173
+ at_end { Benry::CmdApp.undef_action("hello3942") }
174
+ #
175
+ md = Benry::CmdApp::REGISTRY.metadata_get("hello3942")
176
+ ok {md.schema.option_help()} == <<"END"
177
+ -l <lang> : language
178
+ --color[=<on|off>] : color mode
179
+ -i[<N>] : indent
180
+ --silent : silent mode
181
+ END
182
+ end
183
+
184
+ spec "[!bfxye] `@copy_options.()` tries to find an action with current prefix." do
185
+ MyAction.class_eval do
186
+ category "c9588:" do
187
+ @action.("test action")
188
+ @option.(:foo, "--foo", "foo option")
189
+ def action9588(foo: nil)
190
+ end
191
+ #
192
+ @action.("test action")
193
+ @copy_options.("action9588")
194
+ @option.(:bar, "--bar", "bar option")
195
+ def action9588x(foo: nil, bar: nil)
196
+ end
197
+ end
198
+ end
199
+ at_end {
200
+ Benry::CmdApp.undef_action("c9588:action9588")
201
+ Benry::CmdApp.undef_action("c9588:action9588x")
202
+ }
203
+ #
204
+ md = Benry::CmdApp::REGISTRY.metadata_get("c9588:action9588x")
205
+ ok {md.schema.option_help()} == <<END
206
+ --foo : foo option
207
+ --bar : bar option
208
+ END
209
+ end
210
+
211
+ spec "[!mhhn2] `@copy_options.()` raises DefinitionError when action not found." do
212
+ pr = proc do
213
+ MyAction.class_eval do
214
+ @action.("hello 4691")
215
+ @copy_options.("hello469100")
216
+ def hello4691()
217
+ end
218
+ end
219
+ end
220
+ ok {pr}.raise?(Benry::CmdApp::DefinitionError,
221
+ %q|@copy_options.("hello469100"): Action not found.|)
222
+ end
223
+
224
+ spec "[!0slo8] raises DefinitionError if `@copy_options.()` called without `@action.()`." do
225
+ pr = proc do
226
+ MyAction.class_eval do
227
+ @__actiondef__ = nil
228
+ @copy_options.("hello")
229
+ def hello8420()
230
+ end
231
+ end
232
+ end
233
+ ok {pr}.raise?(Benry::CmdApp::DefinitionError,
234
+ %q|@copy_options.("hello"): Called without `@action.()`.|)
235
+ end
236
+
237
+ spec "[!0qz0q] `@copy_options.()` stores arguments into option schema object." do
238
+ x1 = x2 = nil
239
+ MyAction.class_eval do
240
+ @action.("hello")
241
+ x1 = @__actiondef__[1]
242
+ @copy_options.("hello")
243
+ x2 = @__actiondef__[1]
244
+ @__actiondef__ = nil
245
+ end
246
+ ok {x1} != nil
247
+ ok {x2}.same?(x1)
248
+ ok {x2}.is_a?(Benry::CmdApp::ACTION_OPTION_SCHEMA_CLASS)
249
+ ok {x2.to_s()} == <<"END"
250
+ -l, --lang=<lang> : language name (en/fr/it)
251
+ END
252
+ end
253
+
254
+ spec "[!dezh1] `@copy_options.()` ignores help option automatically." do
255
+ x = nil
256
+ MyAction.class_eval do
257
+ @action.("copy of hello")
258
+ @__actiondef__[1] = Benry::CmdApp::ACTION_OPTION_SCHEMA_CLASS.new
259
+ @__actiondef__[1].instance_eval { @items.clear() }
260
+ @copy_options.("hello")
261
+ x = @__actiondef__[1]
262
+ @__actiondef__ = nil
263
+ end
264
+ ok {x} != nil
265
+ ok {x}.is_a?(Benry::CmdApp::ACTION_OPTION_SCHEMA_CLASS)
266
+ ok {x.to_s()} == <<"END"
267
+ -l, --lang=<lang> : language name (en/fr/it)
268
+ END
269
+ end
270
+
271
+ spec "[!7g5ug] sets Proc object to `@optionset` in subclass." do
272
+ _ = self
273
+ MyAction.class_eval do
274
+ _.ok {@optionset} != nil
275
+ _.ok {@optionset}.is_a?(Proc)
276
+ end
277
+ end
278
+
279
+ spec "[!o27kt] raises DefinitionError if `@optionset.()` called without `@action.()`." do
280
+ pr = proc do
281
+ MyAction.class_eval do
282
+ @optionset.()
283
+ end
284
+ end
285
+ ok {pr}.raise?(Benry::CmdApp::DefinitionError,
286
+ "`@optionset.()` called without `@action.()`.")
287
+ end
288
+
289
+ spec "[!ky6sg] copies option items from optionset into schema object." do
290
+ MyAction.class_eval do
291
+ optset1 = optionset do
292
+ @option.(:user, "-u <user>", "user name")
293
+ @option.(:email, "-e <email>", "email address")
294
+ end
295
+ optset2 = optionset do
296
+ @option.(:host, "--host=<host>", "host name")
297
+ @option.(:port, "--port=<port>", "port number", type: Integer)
298
+ end
299
+ #
300
+ @action.("sample")
301
+ @optionset.(optset1, optset2)
302
+ def dummy8173(user: nil, email: nil, host: nil, port: nil)
303
+ end
304
+ end
305
+ metadata = Benry::CmdApp::REGISTRY.metadata_get("dummy8173")
306
+ ok {metadata.schema.to_s} == <<"END"
307
+ -u <user> : user name
308
+ -e <email> : email address
309
+ --host=<host> : host name
310
+ --port=<port> : port number
311
+ END
312
+ end
313
+
314
+ end
315
+
316
+
317
+ topic '._new_option_schema()' do
318
+
319
+ spec "[!zuxmj] creates new option schema object." do
320
+ x = Benry::CmdApp::ActionScope.class_eval { _new_option_schema() }
321
+ ok {x}.is_a?(Benry::CmdApp::ACTION_OPTION_SCHEMA_CLASS)
322
+ end
323
+
324
+ spec "[!rruxi] adds '-h, --help' option as hidden automatically." do
325
+ schema = Benry::CmdApp::ActionScope.class_eval { _new_option_schema() }
326
+ item = schema.get(:help)
327
+ ok {item} != nil
328
+ ok {item.key} == :help
329
+ ok {item.optdef} == "-h, --help"
330
+ ok {item}.hidden?
331
+ end
332
+
333
+ end
334
+
335
+
336
+ topic '.method_added()' do
337
+
338
+ spec "[!6frgx] do nothing if `@action.()` is not called." do
339
+ ScopeTestAction.class_eval { @__actiondef__ = nil }
340
+ x = ScopeTestAction.__send__(:method_added, :foo)
341
+ ok {x} == false
342
+ #
343
+ ScopeTestAction.class_eval do
344
+ def s6732()
345
+ end
346
+ @__actiondef__ = ["test", Benry::CmdApp::OptionSchema.new, {}]
347
+ end
348
+ x = ScopeTestAction.__send__(:method_added, :s6732)
349
+ ok {x} == true
350
+ end
351
+
352
+ spec "[!e3yjo] clears `@__actiondef__`." do
353
+ x1 = nil
354
+ x2 = nil
355
+ ScopeTestAction.class_eval do
356
+ @action.("test")
357
+ x1 = @__actiondef__
358
+ def s4643()
359
+ end
360
+ x2 = @__actiondef__
361
+ end
362
+ ok {x1} != nil
363
+ ok {x2} == nil
364
+ end
365
+
366
+ spec "[!jq4ex] raises DefinitionError if option defined but corresponding keyword arg is missing." do
367
+ pr = proc do
368
+ ScopeTestAction.class_eval do
369
+ @action.("test")
370
+ @option.(:foo, "--foo", "foo option")
371
+ @option.(:bar, "--bar", "bar option")
372
+ def a7913(arg, foo: nil, baz: nil)
373
+ end
374
+ end
375
+ end
376
+ ok {pr}.raise?(Benry::CmdApp::DefinitionError,
377
+ "def a7913(): Keyword argument `bar:` expected which corresponds to the `:bar` option, but not exist.")
378
+ end
379
+
380
+ spec "[!ejdlo] converts method name to action name." do
381
+ ScopeTestAction.class_eval do
382
+ @action.("test")
383
+ def s9321__aa_bb__cc_dd_()
384
+ end
385
+ end
386
+ md = Benry::CmdApp::REGISTRY.metadata_each.find {|x| x.name =~ /s9321/ }
387
+ ok {md} != nil
388
+ ok {md.name} == "s9321:aa-bb:cc-dd"
389
+ end
390
+
391
+ case_when "[!w9qat] when `category()` called before defining action method..." do
392
+
393
+ spec "[!3pl1r] renames method name to new name with prefix." do
394
+ ScopeTestAction.class_eval do
395
+ category "p3442:" do
396
+ category "foo:" do
397
+ category "bar:" do
398
+ @action.("test")
399
+ def s9192()
400
+ end
401
+ end
402
+ end
403
+ end
404
+ end
405
+ ok {ScopeTestAction.method_defined?(:s9192)} == false
406
+ ok {ScopeTestAction.method_defined?(:p3442__foo__bar__s9192)} == true
407
+ end
408
+
409
+ case_when "[!mil2g] when action name matched to 'action:' kwarg of `category()`..." do
410
+
411
+ spec "[!hztpp] uses pefix name as action name." do
412
+ ScopeTestAction.class_eval do
413
+ category "p9782:", action: "s3867" do
414
+ @action.("test")
415
+ def s3867()
416
+ end
417
+ end
418
+ end
419
+ ok {Benry::CmdApp::REGISTRY.metadata_get("p9782:s3867")} == nil
420
+ ok {Benry::CmdApp::REGISTRY.metadata_get("p9782")} != nil
421
+ ok {Benry::CmdApp::REGISTRY.metadata_get("p9782").meth} == :p9782__s3867
422
+ end
423
+
424
+ spec "[!cydex] clears `action:` kwarg." do
425
+ x1 = x2 = x3 = nil
426
+ ScopeTestAction.class_eval do
427
+ category "p3503:", action: "s5319" do
428
+ x1 = @__prefixdef__[1]
429
+ #
430
+ @action.("test")
431
+ def s1767()
432
+ end
433
+ x2 = @__prefixdef__[1]
434
+ #
435
+ @action.("test")
436
+ def s5319()
437
+ end
438
+ x3 = @__prefixdef__[1]
439
+ end
440
+ end
441
+ ok {x1} == "s5319"
442
+ ok {x2} == "s5319"
443
+ ok {x3} == nil
444
+ end
445
+
446
+ end
447
+
448
+ case_when "[!8xsnw] when action name matched to `alias_for:` kwarg of `category()`..." do
449
+
450
+ spec "[!iguvp] adds prefix name to action name." do
451
+ ScopeTestAction.class_eval do
452
+ category "p8134:", alias_for: "s6368" do
453
+ @action.("test")
454
+ def s6368()
455
+ end
456
+ end
457
+ end
458
+ md = Benry::CmdApp::REGISTRY.metadata_each.find {|x| x.name =~ /s6368/ }
459
+ ok {md.name} == "p8134:s6368"
460
+ ok {md}.NOT.alias?
461
+ md = Benry::CmdApp::REGISTRY.metadata_get("p8134")
462
+ ok {md.name} == "p8134"
463
+ ok {md}.alias?
464
+ end
465
+
466
+ end
467
+
468
+ case_when "[!wmevh] else..." do
469
+
470
+ spec "[!9cyc2] adds prefix name to action name." do
471
+ ScopeTestAction.class_eval do
472
+ category "p9986:", alias_for: "s4711" do
473
+ @action.("test")
474
+ def s0629()
475
+ end
476
+ @action.("test")
477
+ def s4711()
478
+ end
479
+ end
480
+ end
481
+ md = Benry::CmdApp::REGISTRY.metadata_each.find {|x| x.name =~ /s0629/ }
482
+ ok {md.name} == "p9986:s0629"
483
+ ok {md}.NOT.alias?
484
+ end
485
+
486
+ end
487
+
488
+ end
489
+
490
+ case_when "[!y8lh0] else..." do
491
+
492
+ spec "[!0ki5g] not add prefix to action name." do
493
+ ScopeTestAction.class_eval do
494
+ category "p2592:", action: "s2619" do
495
+ @action.("test")
496
+ def s4487()
497
+ end
498
+ @action.("test")
499
+ def s2619()
500
+ end
501
+ end
502
+ end
503
+ md = Benry::CmdApp::REGISTRY.metadata_get("p2592:s4487")
504
+ ok {md.name} == "p2592:s4487"
505
+ ok {md}.NOT.alias?
506
+ md = Benry::CmdApp::REGISTRY.metadata_get("p2592")
507
+ ok {md.name} == "p2592"
508
+ ok {md}.NOT.alias?
509
+ end
510
+
511
+ end
512
+
513
+ spec "[!dad1q] raises DefinitionError if action with same name already defined." do
514
+ pr = proc do
515
+ ScopeTestAction.class_eval do
516
+ @action.("duplicate")
517
+ def hello()
518
+ end
519
+ end
520
+ end
521
+ ok {pr}.raise?(Benry::CmdApp::DefinitionError,
522
+ "def hello(): Action 'hello' already defined (to redefine it, delete it beforehand by `undef_action()`).")
523
+ #
524
+ pr = proc do
525
+ ScopeTestAction.class_eval do
526
+ category "git:" do
527
+ @action.("duplicate")
528
+ def stage()
529
+ end
530
+ end
531
+ end
532
+ end
533
+ ok {pr}.raise?(Benry::CmdApp::DefinitionError,
534
+ "def stage(): Action 'git:stage' already defined (to redefine it, delete it beforehand by `undef_action()`).")
535
+ end
536
+
537
+ spec "[!ur8lp] raises DefinitionError if method already defined in parent or ancestor class." do
538
+ pr = proc do
539
+ ScopeTestAction.class_eval do
540
+ @action.("print")
541
+ def print()
542
+ end
543
+ end
544
+ end
545
+ at_end { ScopeTestAction.class_eval { @__actiondef__ = nil } }
546
+ ok {pr}.raise?(Benry::CmdApp::DefinitionError,
547
+ "def print(): Please rename it to `print_()`, because it overrides existing method in parent or ancestor class.")
548
+ end
549
+
550
+ spec "[!dj0ql] method override check is done with new method name (= prefixed name)." do
551
+ pr = proc do
552
+ ScopeTestAction.class_eval do
553
+ category "p2946:" do
554
+ @action.("print")
555
+ def print()
556
+ end
557
+ end
558
+ end
559
+ end
560
+ ok {pr}.NOT.raise?(Exception)
561
+ metadata = Benry::CmdApp::REGISTRY.metadata_get("p2946:print")
562
+ ok {metadata} != nil
563
+ ok {metadata.meth} == :p2946__print
564
+ #
565
+ pr = proc do
566
+ OverrideTestAction2.class_eval do
567
+ category "foo1:"
568
+ @action.("foo1")
569
+ def bar1()
570
+ end
571
+ end
572
+ end
573
+ ok {pr}.raise?(Benry::CmdApp::DefinitionError,
574
+ "def bar1(): Please rename it to `bar1_()`, because it overrides existing method in parent or ancestor class.")
575
+ end
576
+
577
+ spec "[!7fnh4] registers action metadata." do
578
+ ScopeTestAction.class_eval do
579
+ category "p7966:" do
580
+ @action.("test")
581
+ def s3198()
582
+ end
583
+ end
584
+ end
585
+ md = Benry::CmdApp::REGISTRY.metadata_get("p7966:s3198")
586
+ ok {md} != nil
587
+ ok {md.name} == "p7966:s3198"
588
+ ok {md}.NOT.alias?
589
+ end
590
+
591
+ spec "[!lyn0z] registers alias metadata if necessary." do
592
+ ScopeTestAction.class_eval do
593
+ category "p0692:", alias_for: "s8075" do
594
+ @action.("test")
595
+ def s8075()
596
+ end
597
+ end
598
+ end
599
+ md = Benry::CmdApp::REGISTRY.metadata_get("p0692")
600
+ ok {md} != nil
601
+ ok {md}.alias?
602
+ ok {md.action} == "p0692:s8075"
603
+ md = Benry::CmdApp::REGISTRY.metadata_get("p0692:s8075")
604
+ ok {md} != nil
605
+ ok {md}.NOT.alias?
606
+ end
607
+
608
+ spec "[!4402s] clears `alias_for:` kwarg." do
609
+ x1 = x2 = x3 = nil
610
+ ScopeTestAction.class_eval do
611
+ category "p7506:", alias_for: "s3449" do
612
+ x1 = @__prefixdef__[2]
613
+ #
614
+ @action.("test")
615
+ def s8075()
616
+ end
617
+ x2 = @__prefixdef__[2]
618
+ #
619
+ @action.("test")
620
+ def s3449()
621
+ end
622
+ x3 = @__prefixdef__[2]
623
+ end
624
+ end
625
+ x1 == "s3449"
626
+ x2 == "s3449"
627
+ x3 == nil
628
+ end
629
+
630
+ spec "[!u0td6] registers prefix of action if not registered yet." do
631
+ prefix = "p1777:foo:bar:"
632
+ ok {Benry::CmdApp::REGISTRY.category_exist?(prefix)} == false
633
+ ScopeTestAction.class_eval do
634
+ @action.("example")
635
+ def p1777__foo__bar__hello()
636
+ end
637
+ end
638
+ ok {Benry::CmdApp::REGISTRY.category_exist?(prefix)} == true
639
+ end
640
+
641
+ end
642
+
643
+
644
+ topic '.__validate_kwargs()' do
645
+
646
+ spec "[!xpg47] returns nil if `**kwargs` exist." do
647
+ errmsg = ""
648
+ ScopeTestAction.class_eval do
649
+ @action.("dummy")
650
+ @option.(:foo, "--foo", "foo option")
651
+ @option.(:bar, "--bar", "bar option")
652
+ def a5758(foo: nil, bar: nil)
653
+ end
654
+ #
655
+ def a5759(arg1, arg2=nil, foo: nil, baz: nil, **kws)
656
+ end
657
+ md = Benry::CmdApp::REGISTRY.metadata_get("a5758")
658
+ errmsg = __validate_kwargs(:a5759, md.schema)
659
+ end
660
+ ok {errmsg} == nil
661
+ end
662
+
663
+ spec "[!qowwj] returns error message if option defined but corresponding keyword arg is missing." do
664
+ errmsg = nil
665
+ ScopeTestAction.class_eval do
666
+ @action.("dummy")
667
+ @option.(:foo, "--foo", "foo option")
668
+ @option.(:bar, "--bar", "bar option")
669
+ def a5756(foo: nil, bar: nil)
670
+ end
671
+ #
672
+ def a5757(arg1, arg2=nil, foo: nil, baz: nil)
673
+ end
674
+ md = Benry::CmdApp::REGISTRY.metadata_get("a5756")
675
+ errmsg = __validate_kwargs(:a5757, md.schema)
676
+ end
677
+ ok {errmsg} == "Keyword argument `bar:` expected which corresponds to the `:bar` option, but not exist."
678
+ end
679
+
680
+ end
681
+
682
+
683
+ topic '.__validate_action_method()' do
684
+
685
+ spec "[!5a4d3] returns error message if action with same name already defined." do
686
+ x = nil
687
+ ScopeTestAction.class_eval do
688
+ x = __validate_action_method("hello", :tmp__helo, :hello)
689
+ end
690
+ ok {x} == "Action 'hello' already defined (to redefine it, delete it beforehand by `undef_action()`)."
691
+ end
692
+
693
+ spec "[!uxsx3] returns error message if method already defined in parent or ancestor class." do
694
+ x = nil
695
+ ScopeTestAction.class_eval do
696
+ x = __validate_action_method("print", :print, :print)
697
+ end
698
+ ok {x} == "Please rename it to `print_()`, because it overrides existing method in parent or ancestor class."
699
+ end
700
+
701
+ spec "[!3fmpo] method override check is done with new method name (= prefixed name)." do
702
+ x = nil
703
+ ScopeTestAction.class_eval do
704
+ x = __validate_action_method("p3159:print", :print, :xprint)
705
+ end
706
+ ok {x} == "Please rename it to `xprint_()`, because it overrides existing method in parent or ancestor class."
707
+ end
708
+
709
+ end
710
+
711
+
712
+ topic '.current_prefix()' do
713
+
714
+ spec "[!2zt0f] returns current prefix name such as 'foo:bar:'." do
715
+ x1 = x2 = x3 = x4 = x5 = nil
716
+ ScopeTestAction.class_eval do
717
+ x1 = current_prefix()
718
+ category "p9912:" do
719
+ x2 = current_prefix()
720
+ category "p3138:" do
721
+ x3 = current_prefix()
722
+ end
723
+ x4 = current_prefix()
724
+ end
725
+ x5 = current_prefix()
726
+ end
727
+ ok {x1} == nil
728
+ ok {x2} == "p9912:"
729
+ ok {x3} == "p9912:p3138:"
730
+ ok {x4} == "p9912:"
731
+ ok {x5} == nil
732
+ end
733
+
734
+ end
735
+
736
+
737
+ topic '.category()' do
738
+
739
+ spec "[!mp1p5] raises DefinitionError if prefix is invalid." do
740
+ at_end { ScopeTestAction.class_eval { @__prefixdef__ = nil } }
741
+ pr = proc do
742
+ ScopeTestAction.class_eval do
743
+ category "p2737"
744
+ @action.("test")
745
+ def s4393()
746
+ end
747
+ end
748
+ end
749
+ ok {pr}.raise?(Benry::CmdApp::DefinitionError,
750
+ "category(\"p2737\"): Prefix name should end with ':'.")
751
+ end
752
+
753
+ spec "[!q01ma] raises DefinitionError if action or alias name is invalid." do
754
+ pr = proc do
755
+ ScopeTestAction.class_eval { category "p0936:", action: :foo }
756
+ end
757
+ ok {pr}.raise?(Benry::CmdApp::DefinitionError,
758
+ %q|`category("p0936:", action: :foo)`: Action name should be a string, but got Symbol object.|)
759
+ #
760
+ pr = proc do
761
+ ScopeTestAction.class_eval { category "p0936:", alias_for: :bar }
762
+ end
763
+ ok {pr}.raise?(Benry::CmdApp::DefinitionError,
764
+ %q|`category("p0936:", alias_for: :bar)`: Alias name should be a string, but got Symbol object.|)
765
+ #
766
+ pr = proc do
767
+ ScopeTestAction.class_eval { category "p0936:", action: "foo", alias_for: "bar" }
768
+ end
769
+ ok {pr}.raise?(Benry::CmdApp::DefinitionError,
770
+ %q|`category("p0936:", action: "foo", alias_for: "bar")`: `action:` and `alias_for:` are exclusive.|)
771
+ end
772
+
773
+ case_when "[!kwst6] if block given..." do
774
+
775
+ spec "[!t8wwm] saves previous prefix data and restore them at end of block." do
776
+ x1 = x2 = x3 = nil
777
+ ScopeTestAction.class_eval do
778
+ x1 = @__prefixdef__
779
+ category "p4929:" do
780
+ x2 = @__prefixdef__
781
+ @action.("test")
782
+ def s0997()
783
+ end
784
+ end
785
+ x3 = @__prefixdef__
786
+ end
787
+ ok {x1} == nil
788
+ ok {x2} != nil
789
+ ok {x3} == nil
790
+ end
791
+
792
+ spec "[!j00pk] registers prefix and description, even if no actions defined." do
793
+ ScopeTestAction.class_eval do
794
+ category "p0516:", "bla bla" do
795
+ category "git:", "boom boom" do
796
+ end
797
+ end
798
+ end
799
+ ok {Benry::CmdApp::REGISTRY.category_get_desc("p0516:")} == "bla bla"
800
+ ok {Benry::CmdApp::REGISTRY.category_get_desc("p0516:git:")} == "boom boom"
801
+ #
802
+ ScopeTestAction.class_eval do
803
+ category "p3893:", "guu guu", action: "a1" do
804
+ category "git:", "gii gii", alias_for: "a2" do
805
+ @action.("x")
806
+ def a2(); end
807
+ end
808
+ @action.("x")
809
+ def a1(); end
810
+ end
811
+ end
812
+ ok {Benry::CmdApp::REGISTRY.category_get_desc("p3893:")} == "guu guu"
813
+ ok {Benry::CmdApp::REGISTRY.category_get_desc("p3893:git:")} == "gii gii"
814
+ #
815
+ ScopeTestAction.class_eval do
816
+ category "p2358:" do
817
+ end
818
+ end
819
+ ok {Benry::CmdApp::REGISTRY.category_exist?("p2358:")} == true
820
+ end
821
+
822
+ spec "[!w52y5] raises DefinitionError if `action:` specified but target action not defined." do
823
+ at_end { ScopeTestAction.class_eval { @__prefixdef__ = nil } }
824
+ pr = proc do
825
+ ScopeTestAction.class_eval do
826
+ category "p4929:", action: "s7832" do
827
+ @action.("test")
828
+ def s2649()
829
+ end
830
+ end
831
+ end
832
+ end
833
+ ok {pr}.raise?(Benry::CmdApp::DefinitionError,
834
+ %q|category("p4929:", action: "s7832"): Target action not defined.|)
835
+ end
836
+
837
+ spec "[!zs3b5] raises DefinitionError if `alias_for:` specified but target action not defined." do
838
+ at_end { ScopeTestAction.class_eval { @__prefixdef__ = nil } }
839
+ pr = proc do
840
+ ScopeTestAction.class_eval do
841
+ category "p2476:", alias_for: "s6678" do
842
+ @action.("test")
843
+ def s1452()
844
+ end
845
+ end
846
+ end
847
+ end
848
+ ok {pr}.raise?(Benry::CmdApp::DefinitionError,
849
+ %q|category("p2476:", alias_for: "s6678"): Target action of alias not defined.|)
850
+ end
851
+
852
+ end
853
+
854
+ case_when "[!yqhm8] else..." do
855
+
856
+ spec "[!tgux9] just stores arguments into class." do
857
+ ScopeTestAction.class_eval do
858
+ @__prefixdef__ = nil
859
+ category "p6062:"
860
+ end
861
+ x = ScopeTestAction.class_eval { @__prefixdef__ }
862
+ ok {x} == ["p6062:", nil, nil]
863
+ end
864
+
865
+ spec "[!ncskq] registers prefix and description, even if no actions defined." do
866
+ ScopeTestAction.class_eval do
867
+ category "p6712:", "bowow"
868
+ end
869
+ ok {Benry::CmdApp::REGISTRY.category_get_desc("p6712:")} == "bowow"
870
+ #
871
+ ScopeTestAction.class_eval do
872
+ category "p9461:", "hoo hoo", action: "homhom"
873
+ category "p0438:", "yaa yaa", alias_for: "homhom"
874
+ @__prefixdef__ = nil
875
+ end
876
+ ok {Benry::CmdApp::REGISTRY.category_get_desc("p9461:")} == "hoo hoo"
877
+ ok {Benry::CmdApp::REGISTRY.category_get_desc("p0438:")} == "yaa yaa"
878
+ #
879
+ ScopeTestAction.class_eval do
880
+ category "p7217:"
881
+ end
882
+ ok {Benry::CmdApp::REGISTRY.category_exist?("p7217:")} == true
883
+ end
884
+
885
+ end
886
+
887
+ end
888
+
889
+
890
+ topic '.__validate_prefix()' do
891
+
892
+ spec "[!bac19] returns error message if prefix is not a string." do
893
+ errmsg = ScopeTestAction.class_eval { __validate_prefix(:foo) }
894
+ ok {errmsg} == "String expected, but got Symbol."
895
+ end
896
+
897
+ spec "[!608fc] returns error message if prefix doesn't end with ':'." do
898
+ errmsg = ScopeTestAction.class_eval { __validate_prefix("foo") }
899
+ ok {errmsg} == "Prefix name should end with ':'."
900
+ end
901
+
902
+ spec "[!vupza] returns error message if prefix contains '_'." do
903
+ errmsg = ScopeTestAction.class_eval { __validate_prefix("foo_bar:") }
904
+ ok {errmsg} == "Prefix name should not contain '_' (use '-' instead)."
905
+ end
906
+
907
+ spec "[!5vgn3] returns error message if prefix is invalid." do
908
+ errmsg = ScopeTestAction.class_eval { __validate_prefix("123:") }
909
+ ok {errmsg} == "Invalid prefix name."
910
+ end
911
+
912
+ spec "[!7rphu] returns nil if prefix is valid." do
913
+ errmsg = ScopeTestAction.class_eval { __validate_prefix("foo-bar:") }
914
+ ok {errmsg} == nil
915
+ end
916
+
917
+ end
918
+
919
+
920
+ topic '.__validate_action_and_alias()' do
921
+
922
+ spec "[!38ji9] returns error message if action name is not a string." do
923
+ pr = proc do
924
+ ScopeTestAction.class_eval do
925
+ category "p1871:", action: :foo
926
+ end
927
+ end
928
+ ok {pr}.raise?(Benry::CmdApp::DefinitionError,
929
+ %q|`category("p1871:", action: :foo)`: Action name should be a string, but got Symbol object.|)
930
+ end
931
+
932
+ spec "[!qge3m] returns error message if alias name is not a string." do
933
+ pr = proc do
934
+ ScopeTestAction.class_eval do
935
+ category "p7328:", alias_for: :foo
936
+ end
937
+ end
938
+ ok {pr}.raise?(Benry::CmdApp::DefinitionError,
939
+ %q|`category("p7328:", alias_for: :foo)`: Alias name should be a string, but got Symbol object.|)
940
+ end
941
+
942
+ spec "[!ermv8] returns error message if both `action:` and `alias_for:` kwargs are specified." do
943
+ at_end { ScopeTestAction.class_eval { @__prefixdef__ = nil } }
944
+ pr = proc do
945
+ ScopeTestAction.class_eval do
946
+ category "p7549:", action: "s0573", alias_for: "s0573"
947
+ @action.("test")
948
+ def s0573()
949
+ end
950
+ end
951
+ end
952
+ ok {pr}.raise?(Benry::CmdApp::DefinitionError,
953
+ %q|`category("p7549:", action: "s0573", alias_for: "s0573")`: `action:` and `alias_for:` are exclusive.|)
954
+ end
955
+
956
+ end
957
+
958
+
959
+ topic '.define_alias()' do
960
+
961
+ spec "[!tcpuz] just defines an alias when current prefix is nil." do
962
+ ScopeTestAction.class_eval do
963
+ @action.("sample")
964
+ def a7033()
965
+ end
966
+ define_alias "x7033", "a7033"
967
+ end
968
+ md = Benry::CmdApp::REGISTRY.metadata_get("x7033")
969
+ ok {md.action} == "a7033"
970
+ end
971
+
972
+ spec "[!c6duw] defines an alias with prefix when current prefix exist." do
973
+ ScopeTestAction.class_eval do
974
+ category "p8866:" do
975
+ @action.("sample")
976
+ def a5073()
977
+ end
978
+ define_alias "x5073", "a5073"
979
+ end
980
+ end
981
+ md = Benry::CmdApp::REGISTRY.metadata_get("x5073")
982
+ ok {md.action} == "p8866:a5073"
983
+ end
984
+
985
+ spec "[!b8ly2] supports array argument." do
986
+ ScopeTestAction.class_eval do
987
+ category "p2433:" do
988
+ @action.("sample")
989
+ def a9940(arg)
990
+ end
991
+ define_alias "x2433", ["a9940", "abc"]
992
+ end
993
+ end
994
+ md = Benry::CmdApp::REGISTRY.metadata_get("x2433")
995
+ ok {md.action} == "p2433:a9940"
996
+ ok {md.args} == ["abc"]
997
+ end
998
+
999
+ spec "[!0dkrj] keyword arguments are passed to higher function." do
1000
+ ScopeTestAction.class_eval do
1001
+ category "p5582:"
1002
+ @action.("sample")
1003
+ def a1017(arg)
1004
+ end
1005
+ define_alias "x5582", ["a1017", "abc"], hidden: true, important: true, tag: "experimental"
1006
+ @__prefixdef__ = nil
1007
+ end
1008
+ md = Benry::CmdApp::REGISTRY.metadata_get("x5582")
1009
+ ok {md.action} == "p5582:a1017"
1010
+ ok {md.hidden?} == true
1011
+ ok {md.important?} == true
1012
+ ok {md.tag} == "experimental"
1013
+ end
1014
+
1015
+ end
1016
+
1017
+
1018
+ topic '.optionset()' do
1019
+
1020
+ spec "[!us0g4] yields block with dummy action." do
1021
+ _ = self
1022
+ called = false
1023
+ ScopeTestAction.class_eval do
1024
+ optset1 = optionset() do
1025
+ called = true
1026
+ _.ok {@__actiondef__} != nil
1027
+ _.ok {@__actiondef__[0]} == "dummy action by optionset()"
1028
+ end
1029
+ end
1030
+ ok {called} == true
1031
+ end
1032
+
1033
+ spec "[!1idwv] clears default option items." do
1034
+ _ = self
1035
+ ScopeTestAction.class_eval do
1036
+ optset1 = optionset() do
1037
+ schema = @__actiondef__[1]
1038
+ _.ok {schema.each.to_a}.length(0)
1039
+ end
1040
+ end
1041
+ end
1042
+
1043
+ spec "[!sp3hk] clears `@__actiondef__` to make `@action.()` available." do
1044
+ _ = self
1045
+ ScopeTestAction.class_eval do
1046
+ _.ok {@__actiondef__} == nil
1047
+ optset1 = optionset() do
1048
+ _.ok {@__actiondef__} != nil
1049
+ end
1050
+ _.ok {@__actiondef__} == nil
1051
+ end
1052
+ end
1053
+
1054
+ spec "[!mwbyc] returns new OptionSet object which contains option items." do
1055
+ optset1 = nil
1056
+ ScopeTestAction.class_eval do
1057
+ optset1 = optionset() do
1058
+ @option.(:user, "-u, --user=<user>", "user name")
1059
+ @option.(:email, "-e, --email=<email>", "email address")
1060
+ end
1061
+ end
1062
+ ok {optset1}.is_a?(Benry::CmdApp::OptionSet)
1063
+ items = optset1.instance_variable_get(:@items)
1064
+ ok {items[0].key} == :user
1065
+ ok {items[1].key} == :email
1066
+ end
1067
+
1068
+ end
1069
+
1070
+
1071
+ topic '#run_once()' do
1072
+
1073
+ spec "[!nqjxk] runs action and returns true if not runned ever." do
1074
+ scope = MyAction.new(@config)
1075
+ capture_sio do
1076
+ ok {scope.run_once("hello")} == true
1077
+ end
1078
+ end
1079
+
1080
+ spec "[!wcyut] not run action and returns false if already runned." do
1081
+ scope = MyAction.new(@config)
1082
+ sout, serr = capture_sio do
1083
+ ok {scope.run_once("hello")} == true
1084
+ ok {scope.run_once("hello")} == false
1085
+ ok {scope.run_once("hello")} == false
1086
+ end
1087
+ ok {sout} == "Hello, world!\n"
1088
+ end
1089
+
1090
+ end
1091
+
1092
+
1093
+ topic '#run_action()' do
1094
+
1095
+ spec "[!uwi68] runs action and returns true." do
1096
+ scope = MyAction.new(@config)
1097
+ sout, serr = capture_sio do
1098
+ ok {scope.run_action("hello")} == true
1099
+ ok {scope.run_action("hello")} == true
1100
+ ok {scope.run_action("hello")} == true
1101
+ end
1102
+ ok {sout} == "Hello, world!\n" * 3
1103
+ end
1104
+
1105
+ end
1106
+
1107
+
1108
+ topic '#at_end()' do
1109
+
1110
+ spec "[!3mqcz] registers proc object to context object." do
1111
+ context = Benry::CmdApp::ApplicationContext.new(@config)
1112
+ scope = MyAction.new(@config, context)
1113
+ ok {context.instance_variable_get(:@end_blocks)}.length(0)
1114
+ scope.at_end { puts "A" }
1115
+ scope.at_end { puts "B" }
1116
+ ok {context.instance_variable_get(:@end_blocks)}.length(2)
1117
+ ok {context.instance_variable_get(:@end_blocks)}.all? {|x| x.is_a?(Proc) }
1118
+ end
1119
+ end
1120
+
1121
+
1122
+ topic '#option_error()' do
1123
+
1124
+ spec "[!engp2] returns OptionError object." do
1125
+ x = ScopeTestAction.new(nil).instance_eval {
1126
+ option_error("error message e2038")
1127
+ }
1128
+ ok {x}.is_a?(Benry::CmdApp::OptionError)
1129
+ ok {x.message} == "error message e2038"
1130
+ end
1131
+
1132
+ end
1133
+
1134
+
1135
+ topic '#action_error()' do
1136
+
1137
+ spec "[!2m7d6] returns ActionError object." do
1138
+ x = ScopeTestAction.new(nil).instance_eval {
1139
+ action_error("error message e4417")
1140
+ }
1141
+ ok {x}.is_a?(Benry::CmdApp::ActionError)
1142
+ ok {x.message} == "error message e4417"
1143
+ end
1144
+
1145
+ end
1146
+
1147
+
1148
+ end
1149
+
1150
+
1151
+ topic Benry::CmdApp::BuiltInAction do
1152
+
1153
+ before do
1154
+ @config = Benry::CmdApp::Config.new("test app", "1.2.3",
1155
+ app_name: "TestApp", app_command: "testapp",
1156
+ option_verbose: true, option_quiet: true,
1157
+ option_color: true, #option_debug: true,
1158
+ option_trace: true)
1159
+ end
1160
+
1161
+ topic '#help()' do
1162
+
1163
+ spec "[!2n99u] raises ActionError if current application is not nil." do
1164
+ scope = Benry::CmdApp::BuiltInAction.new(@config)
1165
+ pr = proc { scope.help() }
1166
+ ok {pr}.raise?(Benry::CmdApp::ActionError,
1167
+ "'help' action is available only when invoked from application.")
1168
+ end
1169
+
1170
+ spec "[!g0n06] prints application help message if action name not specified." do
1171
+ app = Benry::CmdApp::Application.new(@config)
1172
+ Benry::CmdApp._set_current_app(app)
1173
+ at_end { Benry::CmdApp._set_current_app(nil) }
1174
+ scope = Benry::CmdApp::BuiltInAction.new(@config)
1175
+ sout, serr = capture_sio(tty: true) { scope.help() }
1176
+ ok {sout} =~ /\A\e\[1mTestApp\e\[0m \e\[2m\(1\.2\.3\)\e\[0m --- test app$/
1177
+ ok {sout} =~ /^\e\[1;34mUsage:\e\[0m$/
1178
+ ok {sout} =~ /^\e\[1;34mOptions:\e\[0m$/
1179
+ ok {sout} =~ /^\e\[1;34mActions:\e\[0m$/
1180
+ end
1181
+
1182
+ spec "[!epj74] prints action help message if action name specified." do
1183
+ app = Benry::CmdApp::Application.new(@config)
1184
+ Benry::CmdApp._set_current_app(app)
1185
+ at_end { Benry::CmdApp._set_current_app(nil) }
1186
+ scope = Benry::CmdApp::BuiltInAction.new(@config)
1187
+ sout, serr = capture_sio(tty: true) { scope.help("hello") }
1188
+ ok {sout} =~ /\A\e\[1mtestapp hello\e\[0m --- greeting message$/
1189
+ ok {sout} =~ /^\e\[1;34mUsage:\e\[0m$/
1190
+ ok {sout} =~ /^\e\[1;34mOptions:\e\[0m$/
1191
+ ok {sout} !~ /^\e\[1;34mActions:\e\[0m$/
1192
+ end
1193
+
1194
+ spec "[!2t43b] deletes escape characters from help message when non-color mode." do
1195
+ app = Benry::CmdApp::Application.new(@config)
1196
+ Benry::CmdApp._set_current_app(app)
1197
+ at_end { Benry::CmdApp._set_current_app(nil) }
1198
+ scope = Benry::CmdApp::BuiltInAction.new(@config)
1199
+ #
1200
+ sout, serr = capture_sio(tty: false) { scope.help() }
1201
+ ok {sout} =~ /\ATestApp \(1\.2\.3\) --- test app$/
1202
+ ok {sout} =~ /^Usage:$/
1203
+ ok {sout} =~ /^Options:$/
1204
+ ok {sout} =~ /^Actions:$/
1205
+ #
1206
+ sout, serr = capture_sio(tty: false) { scope.help("hello") }
1207
+ ok {sout} =~ /\Atestapp hello --- greeting message$/
1208
+ ok {sout} =~ /^Usage:$/
1209
+ ok {sout} =~ /^Options:$/
1210
+ ok {sout} !~ /^Actions:$/
1211
+ end
1212
+
1213
+ end
1214
+
1215
+
1216
+ end
1217
+
1218
+
1219
+ end