benry-cmdapp 0.2.0 → 1.0.0

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