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.
- checksums.yaml +4 -4
- data/CHANGES.md +6 -0
- data/README.md +1693 -852
- data/benry-cmdapp.gemspec +3 -3
- data/doc/benry-cmdapp.html +1582 -906
- data/lib/benry/cmdapp.rb +1894 -1060
- data/test/app_test.rb +882 -1078
- data/test/config_test.rb +71 -0
- data/test/context_test.rb +382 -0
- data/test/func_test.rb +302 -82
- data/test/help_test.rb +1054 -553
- data/test/metadata_test.rb +191 -0
- data/test/misc_test.rb +175 -0
- data/test/registry_test.rb +402 -0
- data/test/run_all.rb +4 -3
- data/test/scope_test.rb +1210 -0
- data/test/shared.rb +112 -49
- data/test/util_test.rb +154 -99
- metadata +17 -9
- data/test/action_test.rb +0 -1038
- data/test/index_test.rb +0 -185
data/test/func_test.rb
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
|
-
require 'oktest'
|
4
4
|
|
5
|
-
|
6
|
-
require_relative './shared'
|
5
|
+
require_relative "shared"
|
7
6
|
|
8
7
|
|
9
8
|
Oktest.scope do
|
@@ -12,125 +11,346 @@ Oktest.scope do
|
|
12
11
|
topic Benry::CmdApp do
|
13
12
|
|
14
13
|
|
15
|
-
topic '.
|
14
|
+
topic '.define_alias()' do
|
16
15
|
|
17
|
-
spec "[!
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
16
|
+
spec "[!zawcd] action arg can be a string or an array of string." do
|
17
|
+
pr = proc { Benry::CmdApp.define_alias("a4983-1", "hello") }
|
18
|
+
ok {pr}.NOT.raise?(Exception)
|
19
|
+
pr = proc { Benry::CmdApp.define_alias("a4983-2", ["hello", "-l", "it"]) }
|
20
|
+
ok {pr}.NOT.raise?(Exception)
|
21
|
+
md = Benry::CmdApp.define_alias("a4983-3", ["hello", "-l", "it"])
|
22
|
+
ok {md.name} == "a4983-3"
|
23
|
+
ok {md.action} == "hello"
|
24
|
+
ok {md.args} == ["-l", "it"]
|
25
|
+
end
|
26
|
+
|
27
|
+
spec "[!hqc27] raises DefinitionError if something error exists in alias or action." do
|
28
|
+
pr = proc { Benry::CmdApp.define_alias("hello2", "hello1") }
|
29
|
+
ok {pr}.raise?(Benry::CmdApp::DefinitionError,
|
30
|
+
%q=define_alias("hello2", "hello1"): Action 'hello1' not found.=)
|
31
|
+
end
|
32
|
+
|
33
|
+
spec "[!oo91b] registers new metadata of alias." do
|
34
|
+
metadata = Benry::CmdApp::REGISTRY.metadata_get("tmphello1")
|
35
|
+
ok {metadata} == nil
|
36
|
+
Benry::CmdApp.define_alias("tmphello1", "hello")
|
37
|
+
metadata = Benry::CmdApp::REGISTRY.metadata_get("tmphello1")
|
38
|
+
ok {metadata} != nil
|
39
|
+
ok {metadata}.is_a?(Benry::CmdApp::AliasMetadata)
|
40
|
+
ok {metadata.name} == "tmphello1"
|
41
|
+
ok {metadata.action} == "hello"
|
42
|
+
ok {metadata.args} == []
|
22
43
|
#
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
44
|
+
Benry::CmdApp.define_alias("tmphello2", ["hello", "aa", "bb", "cc"])
|
45
|
+
metadata = Benry::CmdApp::REGISTRY.metadata_get("tmphello2")
|
46
|
+
ok {metadata.args} == ["aa", "bb", "cc"]
|
47
|
+
end
|
48
|
+
|
49
|
+
spec "[!wfbqu] returns alias metadata." do
|
50
|
+
ret = Benry::CmdApp.define_alias("tmphello3", "hello")
|
51
|
+
ok {ret}.is_a?(Benry::CmdApp::AliasMetadata)
|
52
|
+
ok {ret.name} == "tmphello3"
|
53
|
+
ok {ret.action} == "hello"
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
topic '.__validate_alias_and_action()' do
|
60
|
+
|
61
|
+
spec "[!2x1ew] returns error message if alias name is not a string." do
|
62
|
+
pr = proc { Benry::CmdApp.define_alias(:a4869, "hello") }
|
63
|
+
ok {pr}.raise?(Benry::CmdApp::DefinitionError,
|
64
|
+
%q|define_alias(:a4869, "hello"): Alias name should be a string, but got Symbol object.|)
|
65
|
+
end
|
66
|
+
|
67
|
+
spec "[!galce] returns error message if action name is not a string." do
|
68
|
+
pr = proc { Benry::CmdApp.define_alias("a8680", :hello) }
|
69
|
+
ok {pr}.raise?(Benry::CmdApp::DefinitionError,
|
70
|
+
%q|define_alias("a8680", :hello): Action name should be a string, but got Symbol object.|)
|
71
|
+
end
|
72
|
+
|
73
|
+
spec "[!zh0a9] returns error message if other alias already exists." do
|
74
|
+
pr = proc { Benry::CmdApp.define_alias("tmphello4", "hello") }
|
75
|
+
ok {pr}.NOT.raise?(Exception)
|
76
|
+
pr = proc { Benry::CmdApp.define_alias("tmphello4", "hello") }
|
77
|
+
ok {pr}.raise?(Benry::CmdApp::DefinitionError,
|
78
|
+
%q|define_alias("tmphello4", "hello"): Alias 'tmphello4' already defined.|)
|
79
|
+
end
|
80
|
+
|
81
|
+
spec "[!ohow0] returns error message if other action exists with the same name as alias." do
|
82
|
+
pr = proc { Benry::CmdApp.define_alias("testerr1", "hello") }
|
83
|
+
ok {pr}.raise?(Benry::CmdApp::DefinitionError,
|
84
|
+
%q|define_alias("testerr1", "hello"): Can't define new alias 'testerr1' because already defined as an action.|)
|
85
|
+
end
|
86
|
+
|
87
|
+
spec "[!r24qn] returns error message if action doesn't exist." do
|
88
|
+
pr = proc { Benry::CmdApp.define_alias("tmphello6", "hello99") }
|
89
|
+
ok {pr}.raise?(Benry::CmdApp::DefinitionError,
|
90
|
+
%q|define_alias("tmphello6", "hello99"): Action 'hello99' not found.|)
|
91
|
+
end
|
92
|
+
|
93
|
+
spec "[!lxolh] returns error message if action is an alias name." do
|
94
|
+
Benry::CmdApp.define_alias("tmphello6x", "hello")
|
95
|
+
pr = proc { Benry::CmdApp.define_alias("tmphello6y", "tmphello6x") }
|
96
|
+
ok {pr}.raise?(Benry::CmdApp::DefinitionError,
|
97
|
+
%q|define_alias("tmphello6y", "tmphello6x"): 'tmphello6x' should be an action, but is an alias.|)
|
98
|
+
end
|
99
|
+
|
100
|
+
spec "[!b6my2] returns nil if no errors found." do
|
101
|
+
x = Benry::CmdApp.class_eval {
|
102
|
+
__validate_alias_and_action("tmphello7", "hello")
|
28
103
|
}
|
29
|
-
ok {
|
30
|
-
"def delaction2(): Action 'delaction2' already exist.")
|
104
|
+
ok {x} == nil
|
31
105
|
#
|
32
|
-
Benry::CmdApp.
|
106
|
+
pr = proc { Benry::CmdApp.define_alias("tmphello7", "hello") }
|
33
107
|
ok {pr}.NOT.raise?(Exception)
|
34
108
|
end
|
35
109
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
topic '.undef_alias()' do
|
114
|
+
|
115
|
+
spec "[!pk3ya] raises DefinitionError if alias name is not a string." do
|
116
|
+
pr = proc { Benry::CmdApp.undef_alias(:hello) }
|
117
|
+
ok {pr}.raise?(Benry::CmdApp::DefinitionError,
|
118
|
+
%q|`:hello`: Alias name should be a string, but got Symbol object.|)
|
119
|
+
end
|
120
|
+
|
121
|
+
spec "[!krdkt] raises DefinitionError if alias not exist." do
|
122
|
+
pr = proc { Benry::CmdApp.undef_alias("tmphello8") }
|
123
|
+
ok {pr}.raise?(Benry::CmdApp::DefinitionError,
|
124
|
+
%q|undef_alias("tmphello8"): Alias not exist.|)
|
125
|
+
end
|
126
|
+
|
127
|
+
spec "[!juykx] raises DefinitionError if action specified instead of alias." do
|
128
|
+
pr = proc { Benry::CmdApp.undef_alias("hello") }
|
129
|
+
ok {pr}.raise?(Benry::CmdApp::DefinitionError,
|
130
|
+
%q|undef_alias("hello"): Alias expected but action name specified.|)
|
131
|
+
end
|
132
|
+
|
133
|
+
spec "[!ocyso] deletes existing alias." do
|
134
|
+
Benry::CmdApp.define_alias("tmphello9", "hello")
|
135
|
+
Benry::CmdApp.undef_alias("tmphello9")
|
40
136
|
end
|
41
137
|
|
42
138
|
end
|
43
139
|
|
44
140
|
|
45
|
-
topic '.
|
141
|
+
topic '.undef_action()' do
|
142
|
+
|
143
|
+
spec "[!bcyn3] raises DefinitionError if action name is not a string." do
|
144
|
+
pr = proc { Benry::CmdApp.undef_action(:hello) }
|
145
|
+
ok {pr}.raise?(Benry::CmdApp::DefinitionError,
|
146
|
+
"`:hello`: Action name should be a string, but got Symbol object.")
|
147
|
+
end
|
148
|
+
|
149
|
+
spec "[!bvu95] raises error if action not exist." do
|
150
|
+
pr = proc { Benry::CmdApp.undef_action("hello99") }
|
151
|
+
ok {pr}.raise?(Benry::CmdApp::DefinitionError,
|
152
|
+
"undef_action(\"hello99\"): Action not exist.")
|
153
|
+
end
|
154
|
+
|
155
|
+
spec "[!717fw] raises error if alias specified instead of action." do
|
156
|
+
Benry::CmdApp.define_alias("tmphello21", "hello")
|
157
|
+
pr = proc { Benry::CmdApp.undef_action("tmphello21") }
|
158
|
+
ok {pr}.raise?(Benry::CmdApp::DefinitionError,
|
159
|
+
"undef_action(\"tmphello21\"): Action expected but alias name specified.")
|
160
|
+
end
|
46
161
|
|
47
|
-
spec "[!
|
48
|
-
|
49
|
-
@action.("
|
50
|
-
def
|
162
|
+
spec "[!01sx1] deletes existing action." do
|
163
|
+
MyAction.class_eval do
|
164
|
+
@action.("dummy")
|
165
|
+
def dummy2049()
|
166
|
+
end
|
51
167
|
end
|
52
|
-
Benry::CmdApp.
|
53
|
-
|
54
|
-
|
55
|
-
Benry::CmdApp.action_alias("delali2", "delalias2")
|
56
|
-
}
|
57
|
-
ok {pr}.raise?(Benry::CmdApp::AliasDefError,
|
58
|
-
"action_alias(\"delali2\", \"delalias2\"): Alias name duplicated.")
|
59
|
-
#
|
60
|
-
Benry::CmdApp.delete_alias("delali2")
|
61
|
-
ok {pr}.NOT.raise?(Exception)
|
168
|
+
ok {Benry::CmdApp::REGISTRY.metadata_get("dummy2049")} != nil
|
169
|
+
Benry::CmdApp.undef_action("dummy2049")
|
170
|
+
ok {Benry::CmdApp::REGISTRY.metadata_get("dummy2049")} == nil
|
62
171
|
end
|
63
172
|
|
64
|
-
spec "[!
|
65
|
-
|
66
|
-
|
67
|
-
|
173
|
+
spec "[!op8z5] deletes action method from action class." do
|
174
|
+
MyAction.class_eval do
|
175
|
+
@action.("dummy")
|
176
|
+
def dummy4290()
|
177
|
+
end
|
178
|
+
end
|
179
|
+
ok {MyAction.method_defined?(:dummy4290)} == true
|
180
|
+
Benry::CmdApp.undef_action("dummy4290")
|
181
|
+
ok {MyAction.method_defined?(:dummy4290)} == false
|
182
|
+
#
|
183
|
+
MyAction.class_eval do
|
184
|
+
private
|
185
|
+
category "p8902:" do
|
186
|
+
@action.("dummy")
|
187
|
+
def dummy9024()
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
ok {MyAction.private_method_defined?(:p8902__dummy9024)} == true
|
192
|
+
Benry::CmdApp.undef_action("p8902:dummy9024")
|
193
|
+
ok {MyAction.private_method_defined?(:p8902__dummy9024)} == false
|
68
194
|
end
|
69
195
|
|
70
196
|
end
|
71
197
|
|
72
198
|
|
73
|
-
topic '.
|
199
|
+
topic '.define_abbrev()' do
|
200
|
+
|
201
|
+
spec "[!e1fob] raises DefinitionError if error found." do
|
202
|
+
pr = proc { Benry::CmdApp.define_abbrev(:foo, "git:") }
|
203
|
+
ok {pr}.raise?(Benry::CmdApp::DefinitionError,
|
204
|
+
":foo: Abbreviation should be a string, but got Symbol object.")
|
205
|
+
end
|
206
|
+
|
207
|
+
spec "[!ed6hr] registers abbrev with prefix." do
|
208
|
+
ok { Benry::CmdApp::REGISTRY.abbrev_exist?("g99:") } == false
|
209
|
+
Benry::CmdApp.define_abbrev("g99:", "git:")
|
210
|
+
ok { Benry::CmdApp::REGISTRY.abbrev_exist?("g99:") } == true
|
211
|
+
ok { Benry::CmdApp::REGISTRY.abbrev_get_prefix("g99:") } == "git:"
|
212
|
+
end
|
213
|
+
|
214
|
+
def _perform(abbrev, prefix)
|
215
|
+
pr = proc { Benry::CmdApp.define_abbrev(abbrev, prefix) }
|
216
|
+
errmsg = nil
|
217
|
+
ok {pr}.raise?(Benry::CmdApp::DefinitionError) do |exc|
|
218
|
+
errmsg = exc.message
|
219
|
+
end
|
220
|
+
return errmsg
|
221
|
+
end
|
222
|
+
|
223
|
+
spec "[!qfzbp] abbrev should be a string." do
|
224
|
+
ok {_perform(:g11, "git:")} == ":g11: Abbreviation should be a string, but got Symbol object."
|
225
|
+
end
|
226
|
+
|
227
|
+
spec "[!f5isx] abbrev should end with ':'." do
|
228
|
+
ok {_perform("g12", "git:")} == "'g12': Abbreviation should end with ':'."
|
229
|
+
end
|
230
|
+
|
231
|
+
spec "[!r673p] abbrev should not contain unexpected symbol." do
|
232
|
+
ok {_perform("g13@:", "git:")} == "'g13@:': Invalid abbreviation."
|
233
|
+
end
|
234
|
+
|
235
|
+
spec "[!dckvt] abbrev should not exist." do
|
236
|
+
Benry::CmdApp.define_abbrev("g14:", "git:")
|
237
|
+
ok {_perform("g14:", "git:")} == "'g14:': Abbreviation is already defined."
|
238
|
+
end
|
239
|
+
|
240
|
+
spec "[!5djjt] abbrev should not be the same name with existing prefix." do
|
241
|
+
ok {_perform("git:", "git:")} == "'git:': Abbreviation is not available because a prefix with the same name already exists."
|
242
|
+
end
|
243
|
+
|
244
|
+
spec "[!mq4ki] prefix should be a string." do
|
245
|
+
ok {_perform("g15:", :"git:")} == ":\"git:\": Prefix should be a string, but got Symbol object."
|
246
|
+
end
|
74
247
|
|
75
|
-
|
76
|
-
|
77
|
-
@action.("alias test")
|
78
|
-
def a1(); end
|
79
|
-
@action.("alias test")
|
80
|
-
def a2(); end
|
248
|
+
spec "[!a82z3] prefix should end with ':'." do
|
249
|
+
ok {_perform("g16:", "git")} == "'git': Prefix should end with ':'."
|
81
250
|
end
|
82
251
|
|
83
|
-
spec "[!
|
84
|
-
|
85
|
-
ok {Benry::CmdApp::INDEX.alias_exist?("a4")} == true
|
86
|
-
ok {Benry::CmdApp::INDEX.get_alias("a4").alias_name} == "a4"
|
87
|
-
ok {Benry::CmdApp::INDEX.get_alias("a4").action_name} == "alias1:a1"
|
252
|
+
spec "[!eq5iu] prefix should exist." do
|
253
|
+
ok {_perform("g17:", "gittt:")} == "'gittt:': No such prefix."
|
88
254
|
end
|
89
255
|
|
90
|
-
spec "[!
|
91
|
-
Benry::CmdApp.
|
92
|
-
ok {Benry::CmdApp::INDEX.alias_exist?("a8")} == true
|
93
|
-
ok {Benry::CmdApp::INDEX.get_alias("a8").alias_name} == "a8"
|
94
|
-
ok {Benry::CmdApp::INDEX.get_alias("a8").action_name} == "alias1:a1"
|
95
|
-
ok {Benry::CmdApp::INDEX.get_alias("a8").args} == ["Alice", "-l", "it"]
|
256
|
+
spec "[!jzkhc] returns nil if no error found." do
|
257
|
+
ok {Benry::CmdApp.define_abbrev("g18:", "git:")} == nil
|
96
258
|
end
|
97
259
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
260
|
+
end
|
261
|
+
|
262
|
+
|
263
|
+
topic '.current_app()' do
|
264
|
+
|
265
|
+
spec "[!xdjce] returns current application." do
|
266
|
+
app = Benry::CmdApp::Application.new(Benry::CmdApp::Config.new(""))
|
267
|
+
Benry::CmdApp._set_current_app(app)
|
268
|
+
ok {Benry::CmdApp.current_app()}.same?(app)
|
103
269
|
end
|
104
270
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
271
|
+
end
|
272
|
+
|
273
|
+
|
274
|
+
topic '._set_current_app()' do
|
275
|
+
|
276
|
+
spec "[!1yqwl] sets current application." do
|
277
|
+
app = Benry::CmdApp::Application.new(Benry::CmdApp::Config.new(""))
|
278
|
+
Benry::CmdApp._set_current_app(app)
|
279
|
+
ok {Benry::CmdApp.current_app()}.same?(app)
|
280
|
+
Benry::CmdApp._set_current_app(nil)
|
281
|
+
ok {Benry::CmdApp.current_app()} == nil
|
110
282
|
end
|
111
283
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
284
|
+
end
|
285
|
+
|
286
|
+
|
287
|
+
topic '.main()' do
|
288
|
+
|
289
|
+
spec "[!6mfxt] accepts the same arguments as 'Config#initialize()'." do
|
290
|
+
ARGV.clear()
|
291
|
+
ARGV.push("-h", "-a")
|
292
|
+
at_end { ARGV.clear() }
|
293
|
+
sout, serr = capture_sio do
|
294
|
+
Benry::CmdApp.main("Sample App", "1.2.0", app_command: "sampleapp", option_verbose: true)
|
295
|
+
end
|
296
|
+
ok {serr} == ""
|
297
|
+
ok {sout}.start_with?(<<END)
|
298
|
+
sampleapp (1.2.0) --- Sample App
|
299
|
+
END
|
300
|
+
ok {sout} =~ /^ --debug : debug mode$/
|
116
301
|
end
|
117
302
|
|
118
|
-
spec "[!
|
119
|
-
|
120
|
-
|
121
|
-
|
303
|
+
spec "[!scpwa] runs application." do
|
304
|
+
ARGV.clear()
|
305
|
+
ARGV.push("-h", "-a")
|
306
|
+
at_end { ARGV.clear() }
|
307
|
+
sout, serr = capture_sio do
|
308
|
+
Benry::CmdApp.main("Sample App", "1.2.0", app_command: "sampleapp", option_verbose: true)
|
309
|
+
end
|
310
|
+
ok {serr} == ""
|
311
|
+
ok {sout}.start_with?(<<END)
|
312
|
+
sampleapp (1.2.0) --- Sample App
|
313
|
+
|
314
|
+
Usage:
|
315
|
+
$ sampleapp [<options>] <action> [<arguments>...]
|
316
|
+
|
317
|
+
Options:
|
318
|
+
-h, --help : print help message (of action if specified)
|
319
|
+
-V, --version : print version
|
320
|
+
-l, --list : list actions and aliases
|
321
|
+
-L <topic> : topic list (actions|aliases|categories|abbrevs)
|
322
|
+
-a, --all : list hidden actions/options, too
|
323
|
+
-v, --verbose : verbose mode
|
324
|
+
--debug : debug mode
|
325
|
+
|
326
|
+
Actions:
|
327
|
+
END
|
122
328
|
end
|
123
329
|
|
124
|
-
spec "[!
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
330
|
+
spec "[!jbv9z] returns the status code." do
|
331
|
+
ARGV.clear()
|
332
|
+
ARGV.push("-h", "-a")
|
333
|
+
at_end { ARGV.clear() }
|
334
|
+
status_code = nil
|
335
|
+
#
|
336
|
+
sout, serr = capture_sio do
|
337
|
+
status_code = Benry::CmdApp.main("Sample App", "1.2.0")
|
338
|
+
end
|
339
|
+
ok {serr} == ""
|
340
|
+
ok {status_code} == 0
|
341
|
+
#
|
342
|
+
ARGV.clear()
|
343
|
+
ARGV.push("--blabla")
|
344
|
+
sout, serr = capture_sio do
|
345
|
+
status_code = Benry::CmdApp.main("Sample App", "1.2.0")
|
346
|
+
end
|
347
|
+
ok {serr} == "[ERROR] --blabla: Unknown long option.\n"
|
348
|
+
ok {status_code} == 1
|
130
349
|
end
|
131
350
|
|
132
351
|
end
|
133
352
|
|
353
|
+
|
134
354
|
end
|
135
355
|
|
136
356
|
|