trepanning 0.0.4
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/ChangeLog +4422 -0
- data/LICENSE +23 -0
- data/NEWS +12 -0
- data/README.textile +56 -0
- data/Rakefile +171 -0
- data/app/Makefile +7 -0
- data/app/breakpoint.rb +157 -0
- data/app/brkptmgr.rb +149 -0
- data/app/condition.rb +22 -0
- data/app/core.rb +203 -0
- data/app/default.rb +54 -0
- data/app/disassemble.rb +61 -0
- data/app/display.rb +148 -0
- data/app/file.rb +135 -0
- data/app/frame.rb +275 -0
- data/app/irb.rb +112 -0
- data/app/mock.rb +22 -0
- data/app/options.rb +122 -0
- data/app/run.rb +95 -0
- data/app/thread.rb +24 -0
- data/app/util.rb +32 -0
- data/bin/trepan +63 -0
- data/data/custom_require.rb +44 -0
- data/data/irbrc +55 -0
- data/data/prelude.rb +38 -0
- data/interface/base_intf.rb +95 -0
- data/interface/script.rb +103 -0
- data/interface/user.rb +90 -0
- data/io/base_io.rb +92 -0
- data/io/input.rb +111 -0
- data/io/string_array.rb +155 -0
- data/lib/Makefile +7 -0
- data/lib/trepanning.rb +277 -0
- data/processor/breakpoint.rb +108 -0
- data/processor/command/alias.rb +55 -0
- data/processor/command/backtrace.rb +95 -0
- data/processor/command/base/cmd.rb +97 -0
- data/processor/command/base/subcmd.rb +207 -0
- data/processor/command/base/submgr.rb +178 -0
- data/processor/command/base/subsubcmd.rb +102 -0
- data/processor/command/base/subsubmgr.rb +182 -0
- data/processor/command/break.rb +85 -0
- data/processor/command/condition.rb +64 -0
- data/processor/command/continue.rb +61 -0
- data/processor/command/debug.rb +85 -0
- data/processor/command/delete.rb +54 -0
- data/processor/command/directory.rb +43 -0
- data/processor/command/disable.rb +65 -0
- data/processor/command/disassemble.rb +103 -0
- data/processor/command/display.rb +81 -0
- data/processor/command/down.rb +56 -0
- data/processor/command/enable.rb +43 -0
- data/processor/command/exit.rb +54 -0
- data/processor/command/finish.rb +81 -0
- data/processor/command/frame.rb +117 -0
- data/processor/command/help.rb +146 -0
- data/processor/command/info.rb +28 -0
- data/processor/command/info_subcmd/args.rb +56 -0
- data/processor/command/info_subcmd/breakpoints.rb +162 -0
- data/processor/command/info_subcmd/file.rb +162 -0
- data/processor/command/info_subcmd/frame.rb +39 -0
- data/processor/command/info_subcmd/iseq.rb +83 -0
- data/processor/command/info_subcmd/locals.rb +88 -0
- data/processor/command/info_subcmd/program.rb +54 -0
- data/processor/command/info_subcmd/registers.rb +72 -0
- data/processor/command/info_subcmd/registers_subcmd/dfp.rb +38 -0
- data/processor/command/info_subcmd/registers_subcmd/helper.rb +40 -0
- data/processor/command/info_subcmd/registers_subcmd/lfp.rb +54 -0
- data/processor/command/info_subcmd/registers_subcmd/pc.rb +44 -0
- data/processor/command/info_subcmd/registers_subcmd/sp.rb +75 -0
- data/processor/command/info_subcmd/return.rb +40 -0
- data/processor/command/info_subcmd/thread.rb +106 -0
- data/processor/command/irb.rb +106 -0
- data/processor/command/kill.rb +58 -0
- data/processor/command/list.rb +327 -0
- data/processor/command/macro.rb +65 -0
- data/processor/command/next.rb +89 -0
- data/processor/command/nocache.rb +33 -0
- data/processor/command/print.rb +37 -0
- data/processor/command/ps.rb +40 -0
- data/processor/command/quit.rb +62 -0
- data/processor/command/raise.rb +47 -0
- data/processor/command/reload.rb +28 -0
- data/processor/command/reload_subcmd/command.rb +34 -0
- data/processor/command/restart.rb +57 -0
- data/processor/command/save.rb +60 -0
- data/processor/command/set.rb +47 -0
- data/processor/command/set_subcmd/auto.rb +27 -0
- data/processor/command/set_subcmd/auto_subcmd/eval.rb +67 -0
- data/processor/command/set_subcmd/auto_subcmd/irb.rb +49 -0
- data/processor/command/set_subcmd/auto_subcmd/list.rb +51 -0
- data/processor/command/set_subcmd/basename.rb +39 -0
- data/processor/command/set_subcmd/debug.rb +27 -0
- data/processor/command/set_subcmd/debug_subcmd/dbgr.rb +49 -0
- data/processor/command/set_subcmd/debug_subcmd/except.rb +35 -0
- data/processor/command/set_subcmd/debug_subcmd/macro.rb +35 -0
- data/processor/command/set_subcmd/debug_subcmd/skip.rb +35 -0
- data/processor/command/set_subcmd/debug_subcmd/stack.rb +45 -0
- data/processor/command/set_subcmd/different.rb +67 -0
- data/processor/command/set_subcmd/events.rb +71 -0
- data/processor/command/set_subcmd/max.rb +35 -0
- data/processor/command/set_subcmd/max_subcmd/list.rb +50 -0
- data/processor/command/set_subcmd/max_subcmd/stack.rb +60 -0
- data/processor/command/set_subcmd/max_subcmd/string.rb +53 -0
- data/processor/command/set_subcmd/max_subcmd/width.rb +50 -0
- data/processor/command/set_subcmd/return.rb +66 -0
- data/processor/command/set_subcmd/sp.rb +62 -0
- data/processor/command/set_subcmd/substitute.rb +25 -0
- data/processor/command/set_subcmd/substitute_subcmd/eval.rb +98 -0
- data/processor/command/set_subcmd/substitute_subcmd/path.rb +55 -0
- data/processor/command/set_subcmd/substitute_subcmd/string.rb +72 -0
- data/processor/command/set_subcmd/timer.rb +68 -0
- data/processor/command/set_subcmd/trace.rb +43 -0
- data/processor/command/set_subcmd/trace_subcmd/buffer.rb +56 -0
- data/processor/command/set_subcmd/trace_subcmd/print.rb +54 -0
- data/processor/command/set_subcmd/trace_subcmd/var.rb +61 -0
- data/processor/command/show.rb +27 -0
- data/processor/command/show_subcmd/alias.rb +50 -0
- data/processor/command/show_subcmd/args.rb +50 -0
- data/processor/command/show_subcmd/auto.rb +27 -0
- data/processor/command/show_subcmd/auto_subcmd/eval.rb +38 -0
- data/processor/command/show_subcmd/auto_subcmd/irb.rb +34 -0
- data/processor/command/show_subcmd/auto_subcmd/list.rb +36 -0
- data/processor/command/show_subcmd/basename.rb +28 -0
- data/processor/command/show_subcmd/debug.rb +27 -0
- data/processor/command/show_subcmd/debug_subcmd/dbgr.rb +31 -0
- data/processor/command/show_subcmd/debug_subcmd/except.rb +33 -0
- data/processor/command/show_subcmd/debug_subcmd/macro.rb +32 -0
- data/processor/command/show_subcmd/debug_subcmd/skip.rb +33 -0
- data/processor/command/show_subcmd/debug_subcmd/stack.rb +32 -0
- data/processor/command/show_subcmd/different.rb +37 -0
- data/processor/command/show_subcmd/events.rb +40 -0
- data/processor/command/show_subcmd/macro.rb +45 -0
- data/processor/command/show_subcmd/max.rb +31 -0
- data/processor/command/show_subcmd/max_subcmd/list.rb +39 -0
- data/processor/command/show_subcmd/max_subcmd/stack.rb +35 -0
- data/processor/command/show_subcmd/max_subcmd/string.rb +41 -0
- data/processor/command/show_subcmd/max_subcmd/width.rb +36 -0
- data/processor/command/show_subcmd/trace.rb +29 -0
- data/processor/command/show_subcmd/trace_subcmd/buffer.rb +84 -0
- data/processor/command/show_subcmd/trace_subcmd/print.rb +38 -0
- data/processor/command/source.rb +74 -0
- data/processor/command/step.rb +139 -0
- data/processor/command/stepi.rb +63 -0
- data/processor/command/unalias.rb +44 -0
- data/processor/command/undisplay.rb +63 -0
- data/processor/command/up.rb +92 -0
- data/processor/default.rb +45 -0
- data/processor/display.rb +17 -0
- data/processor/eval.rb +88 -0
- data/processor/eventbuf.rb +131 -0
- data/processor/frame.rb +230 -0
- data/processor/help.rb +72 -0
- data/processor/hook.rb +128 -0
- data/processor/load_cmds.rb +102 -0
- data/processor/location.rb +126 -0
- data/processor/main.rb +364 -0
- data/processor/mock.rb +100 -0
- data/processor/msg.rb +26 -0
- data/processor/running.rb +170 -0
- data/processor/subcmd.rb +159 -0
- data/processor/validate.rb +395 -0
- data/test/example/fname with blank.rb +1 -0
- data/test/example/gcd-xx.rb +18 -0
- data/test/example/gcd.rb +19 -0
- data/test/example/gcd1.rb +24 -0
- data/test/example/null.rb +1 -0
- data/test/example/thread1.rb +3 -0
- data/test/functional/fn_helper.rb +119 -0
- data/test/functional/test-break.rb +87 -0
- data/test/functional/test-condition.rb +59 -0
- data/test/functional/test-debugger-call-bug.rb +31 -0
- data/test/functional/test-delete.rb +71 -0
- data/test/functional/test-finish.rb +44 -0
- data/test/functional/test-immediate-step-bug.rb +35 -0
- data/test/functional/test-next.rb +77 -0
- data/test/functional/test-raise.rb +73 -0
- data/test/functional/test-return.rb +100 -0
- data/test/functional/test-step.rb +274 -0
- data/test/functional/test-stepbug.rb +40 -0
- data/test/functional/test-trace-var.rb +40 -0
- data/test/functional/tmp/b1.rb +5 -0
- data/test/functional/tmp/s1.rb +9 -0
- data/test/functional/tmp/t2.rb +6 -0
- data/test/integration/file-diff.rb +88 -0
- data/test/integration/helper.rb +52 -0
- data/test/integration/test-fname-with-blank.rb +11 -0
- data/test/integration/test-quit.rb +11 -0
- data/test/integration/try-test-enable.rb +11 -0
- data/test/unit/cmd-helper.rb +44 -0
- data/test/unit/test-app-brkpt.rb +30 -0
- data/test/unit/test-app-brkptmgr.rb +56 -0
- data/test/unit/test-app-disassemble.rb +60 -0
- data/test/unit/test-app-file.rb +46 -0
- data/test/unit/test-app-frame.rb +49 -0
- data/test/unit/test-app-options.rb +60 -0
- data/test/unit/test-app-run.rb +19 -0
- data/test/unit/test-app-thread.rb +25 -0
- data/test/unit/test-app-util.rb +17 -0
- data/test/unit/test-base-subcmd.rb +59 -0
- data/test/unit/test-bin-trepan.rb +48 -0
- data/test/unit/test-cmd-alias.rb +50 -0
- data/test/unit/test-cmd-break.rb +80 -0
- data/test/unit/test-cmd-endisable.rb +59 -0
- data/test/unit/test-cmd-help.rb +100 -0
- data/test/unit/test-cmd-kill.rb +47 -0
- data/test/unit/test-cmd-quit.rb +26 -0
- data/test/unit/test-cmd-step.rb +45 -0
- data/test/unit/test-intf-user.rb +45 -0
- data/test/unit/test-io-input.rb +26 -0
- data/test/unit/test-proc-eval.rb +26 -0
- data/test/unit/test-proc-frame.rb +77 -0
- data/test/unit/test-proc-help.rb +15 -0
- data/test/unit/test-proc-hook.rb +29 -0
- data/test/unit/test-proc-load_cmds.rb +40 -0
- data/test/unit/test-proc-main.rb +99 -0
- data/test/unit/test-proc-validate.rb +90 -0
- data/test/unit/test-subcmd-help.rb +48 -0
- metadata +358 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require 'test/unit'
|
|
3
|
+
require_relative '../../app/disassemble'
|
|
4
|
+
|
|
5
|
+
# Test Trepan::CmdProcessor
|
|
6
|
+
class TestAppDisassemble < Test::Unit::TestCase
|
|
7
|
+
|
|
8
|
+
include Trepan::Disassemble
|
|
9
|
+
|
|
10
|
+
def setup
|
|
11
|
+
@dis_string='
|
|
12
|
+
local table (size: 6, argc: 1 [opts: 0, rest: -1, post: 0, block: -1] s1)
|
|
13
|
+
[ 6] relative_feature<Arg>[ 5] c [ 4] e [ 3] file [ 2] absolute_feature
|
|
14
|
+
0000 trace 8 ( 26)
|
|
15
|
+
0002 trace 1 ( 27)
|
|
16
|
+
0004 putnil
|
|
17
|
+
'
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def test_mark_dissassembly
|
|
21
|
+
# Check marking pc offset.
|
|
22
|
+
[[-1, -1], [1, -1], [2, 4], [10, -1]].each do |pc_offset, pos|
|
|
23
|
+
ary = mark_disassembly(@dis_string, true, pc_offset)
|
|
24
|
+
selected = ary.select{|line| line =~ /\d{4} / && line !~ /^ /}
|
|
25
|
+
if pos == -1
|
|
26
|
+
assert_equal([], selected,
|
|
27
|
+
'All lines should not be marked')
|
|
28
|
+
else
|
|
29
|
+
assert_equal(1, selected.size,
|
|
30
|
+
"Should have found exectly one PC mark at #{pos}" +
|
|
31
|
+
"\n%s" % ary.join("\n"))
|
|
32
|
+
assert_equal(0, ary[pos] =~ /^ --> /,
|
|
33
|
+
"Should have marked PC at position #{pos}" +
|
|
34
|
+
"\n%s" % ary.join("\n"))
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Check marking breakpoints.
|
|
39
|
+
|
|
40
|
+
[[2, []], [2, [2]], [10, [0, 4]]].each do |pc_offset, brkpts|
|
|
41
|
+
ary = mark_disassembly(@dis_string, true, pc_offset, brkpts)
|
|
42
|
+
selected = ary.select{|line| line =~ /\d{4} / && line !~ /^ /}
|
|
43
|
+
assert_equal(brkpts.size, selected.size,
|
|
44
|
+
"Should have found #{brkpts.size} lines " +
|
|
45
|
+
"at #{brkpts.join(',')}" +
|
|
46
|
+
("\n%s" % ary.join("\n")))
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def test_disassemble_split
|
|
51
|
+
expect = {
|
|
52
|
+
0=>
|
|
53
|
+
"0000 trace 8 ( 26)",
|
|
54
|
+
2=>
|
|
55
|
+
"0002 trace 1 ( 27)",
|
|
56
|
+
4=>"0004 putnil "
|
|
57
|
+
}
|
|
58
|
+
assert_equal(expect, disassemble_split(@dis_string))
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require 'test/unit'
|
|
3
|
+
require_relative '../../app/file'
|
|
4
|
+
|
|
5
|
+
if defined?(SCRIPT_ISEQS__) && SCRIPT_ISEQS__.is_a?(Hash)
|
|
6
|
+
SCRIPT_ISEQS__.clear
|
|
7
|
+
else
|
|
8
|
+
SCRIPT_ISEQS__ = {}
|
|
9
|
+
end
|
|
10
|
+
if defined?(ISEQS__) && ISEQS__.is_a?(Hash)
|
|
11
|
+
ISEQS__.clear
|
|
12
|
+
else
|
|
13
|
+
ISEQS__ = {}
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# To have something to work with.
|
|
17
|
+
load 'tmpdir.rb'
|
|
18
|
+
|
|
19
|
+
class TestAppFile < Test::Unit::TestCase
|
|
20
|
+
include Trepanning
|
|
21
|
+
|
|
22
|
+
def test_file_match_pat
|
|
23
|
+
assert_equal('(?:^|[/])abc\.rb$', file_match_pat('abc.rb'))
|
|
24
|
+
assert_equal('^/a/abc\.rb$', file_match_pat('/a/abc.rb'))
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def test_find_iseqs
|
|
28
|
+
iseqs = find_iseqs(ISEQS__, "tmpdir")
|
|
29
|
+
assert_equal(false, iseqs.empty?)
|
|
30
|
+
iseqs = find_iseqs(ISEQS__, "tmpdir@#{__FILE__}")
|
|
31
|
+
assert_equal(true, iseqs.empty?)
|
|
32
|
+
iseqs = find_iseqs(ISEQS__, "tmpdir@tmpdir.rb")
|
|
33
|
+
assert_equal(false, iseqs.empty?)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def test_find_scripts
|
|
37
|
+
[['tmpdir.rb', true], ['/tmpdir.rb', false],
|
|
38
|
+
['sometmpdir.rb', false]].each do
|
|
39
|
+
|filename, expected|
|
|
40
|
+
found = find_scripts(filename)
|
|
41
|
+
assert_equal(expected, !found.empty?,
|
|
42
|
+
"Should %shave found %s; got %s" %
|
|
43
|
+
[expected ? '' : 'not ', filename, found.inspect])
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require 'test/unit'
|
|
3
|
+
require_relative '../../app/frame'
|
|
4
|
+
require 'thread_frame'
|
|
5
|
+
|
|
6
|
+
class TestAppFrame < Test::Unit::TestCase
|
|
7
|
+
|
|
8
|
+
include Trepan::Frame
|
|
9
|
+
|
|
10
|
+
def test_app_frame
|
|
11
|
+
frame = RubyVM::ThreadFrame.current
|
|
12
|
+
base_count = frame.stack_size
|
|
13
|
+
s = format_stack_entry(frame)
|
|
14
|
+
pat = /^METHOD .*#test_app_frame\(\) in file .*test-app-frame.rb at line \d+/
|
|
15
|
+
assert(s =~ pat, "got #{s}, expected pat #{pat}")
|
|
16
|
+
1.times do
|
|
17
|
+
assert_equal(base_count+2, RubyVM::ThreadFrame.current.stack_size)
|
|
18
|
+
s = format_stack_entry(frame)
|
|
19
|
+
assert(s =~ pat, "got #{s}, expected pat #{pat}")
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def inner_test(count)
|
|
23
|
+
frame = RubyVM::ThreadFrame.current
|
|
24
|
+
assert_equal(count, frame.stack_size)
|
|
25
|
+
|
|
26
|
+
s = format_stack_entry(frame)
|
|
27
|
+
pat = /^METHOD .*#inner_test\(count\) in file .*test-app-frame.rb at line \d+/
|
|
28
|
+
assert(s =~ pat, "got: #{s.inspect},\nexpected: pat #{pat}")
|
|
29
|
+
|
|
30
|
+
s = format_stack_entry(frame, :basename => true)
|
|
31
|
+
pat = /^METHOD .*#inner_test\(count\) in file test-app-frame.rb at line \d+/
|
|
32
|
+
assert(s =~ pat, "got: #{s.inspect},\nexpected: pat #{pat}")
|
|
33
|
+
|
|
34
|
+
s = format_stack_entry(frame, :basename => true, :show_pc => true)
|
|
35
|
+
pat = /^METHOD .*#inner_test\(count\) in file test-app-frame.rb at line \d+, pc: \d+/
|
|
36
|
+
assert(s =~ pat, "got: #{s.inspect},\nexpected: pat #{pat}")
|
|
37
|
+
end
|
|
38
|
+
inner_test(base_count+1)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def test_return
|
|
42
|
+
assert_equal(1, offset_for_return('return'))
|
|
43
|
+
assert_equal(2, offset_for_return('c-return'))
|
|
44
|
+
assert_raises RuntimeError do
|
|
45
|
+
offset_for_return('c-call')
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require 'test/unit'
|
|
3
|
+
require 'stringio'
|
|
4
|
+
require 'tempfile'
|
|
5
|
+
require_relative '../../app/options'
|
|
6
|
+
|
|
7
|
+
# To have something to work with.
|
|
8
|
+
load 'tmpdir.rb'
|
|
9
|
+
|
|
10
|
+
class TestAppStringIO < Test::Unit::TestCase
|
|
11
|
+
include Trepanning
|
|
12
|
+
|
|
13
|
+
def setup
|
|
14
|
+
@options = DEFAULT_CMDLINE_SETTINGS.clone
|
|
15
|
+
@stderr = StringIO.new
|
|
16
|
+
@stdout = StringIO.new
|
|
17
|
+
@options = copy_default_options
|
|
18
|
+
@opts = setup_options(@options, @stdout, @stderr)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def test_cd
|
|
22
|
+
rest = @opts.parse(['--cd', Dir.tmpdir])
|
|
23
|
+
assert_equal(Dir.tmpdir, @options[:chdir])
|
|
24
|
+
assert_equal('', @stderr.string)
|
|
25
|
+
assert_equal('', @stdout.string)
|
|
26
|
+
|
|
27
|
+
setup
|
|
28
|
+
tf = Tempfile.new("delete-me")
|
|
29
|
+
orig_cd = @options[:chdir]
|
|
30
|
+
rest = @opts.parse(['--cd', tf.path])
|
|
31
|
+
assert_equal(orig_cd, @options[:chdir])
|
|
32
|
+
assert_not_equal('', @stderr.string)
|
|
33
|
+
assert_equal('', @stdout.string)
|
|
34
|
+
# FIXME: add test where directory isn't executable.
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def test_binary_opts
|
|
38
|
+
%w(nx).each do |name|
|
|
39
|
+
setup
|
|
40
|
+
o = ["--#{name}"]
|
|
41
|
+
rest = @opts.parse o
|
|
42
|
+
assert_equal('', @stderr.string)
|
|
43
|
+
assert_equal(true, @options[name.to_sym])
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def test_help_and_version_opts
|
|
48
|
+
%w(help version).each do |name|
|
|
49
|
+
setup
|
|
50
|
+
o = ["--#{name}"]
|
|
51
|
+
rest = @opts.parse o
|
|
52
|
+
assert_not_equal('', @stdout.string)
|
|
53
|
+
assert_equal('', @stderr.string)
|
|
54
|
+
assert_equal(true, @options[name.to_sym])
|
|
55
|
+
other_sym = 'help' == name ? :version : :help
|
|
56
|
+
assert_equal(false, @options.member?(other_sym))
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require 'test/unit'
|
|
3
|
+
require_relative '../../app/run'
|
|
4
|
+
|
|
5
|
+
class TestAppRun < Test::Unit::TestCase
|
|
6
|
+
include Trepanning
|
|
7
|
+
def test_basic
|
|
8
|
+
assert_equal(true, File.executable?(whence_file('irb')))
|
|
9
|
+
ng = whence_file('probably-does-not-exist')
|
|
10
|
+
assert_equal(true, File.executable?(ng) || ng == 'probably-does-not-exist')
|
|
11
|
+
rp = ruby_path
|
|
12
|
+
assert_equal(true, File.executable?(rp))
|
|
13
|
+
tup = explicit_restart_argv(ARGV)
|
|
14
|
+
assert_equal(rp, tup[0])
|
|
15
|
+
assert_equal(true, File.readable?(tup[1]))
|
|
16
|
+
assert_equal(ARGV.size + 2, tup.size)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require 'test/unit'
|
|
3
|
+
require_relative '../../app/thread'
|
|
4
|
+
|
|
5
|
+
class TestAppThread < Test::Unit::TestCase
|
|
6
|
+
include Trepan::ThreadHelper
|
|
7
|
+
|
|
8
|
+
def test_basic
|
|
9
|
+
Object::Thread.new do
|
|
10
|
+
th_main = Thread.main
|
|
11
|
+
th_current = Thread.current
|
|
12
|
+
[[ 0, th_main],
|
|
13
|
+
[ 1, th_current],
|
|
14
|
+
[-1, th_current],
|
|
15
|
+
[-2, th_main],
|
|
16
|
+
[2, nil], [-3, nil],
|
|
17
|
+
[Thread.main.object_id, th_main],
|
|
18
|
+
[Thread.current.object_id, th_current]].each do
|
|
19
|
+
|th_num, expected_th|
|
|
20
|
+
assert_equal(expected_th, get_thread(th_num),
|
|
21
|
+
"get_thread(#{th_num}) should be expected")
|
|
22
|
+
end
|
|
23
|
+
end.join
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require 'test/unit'
|
|
3
|
+
require_relative '../../app/util'
|
|
4
|
+
|
|
5
|
+
class TestAppUtil < Test::Unit::TestCase
|
|
6
|
+
include Trepan::Util
|
|
7
|
+
def test_safe_repr
|
|
8
|
+
string = 'The time has come to talk of many things.'
|
|
9
|
+
assert_equal(string, safe_repr(string, 50))
|
|
10
|
+
assert_equal('The time has come...', safe_repr(string, 17))
|
|
11
|
+
assert_equal('The time has come', safe_repr(string, 17, ''))
|
|
12
|
+
assert_equal('"The time has co"...', safe_repr(string.inspect, 17))
|
|
13
|
+
string = "'The time has come to talk of many things.'"
|
|
14
|
+
assert_equal("'The time has co'...", safe_repr(string, 17))
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require 'test/unit'
|
|
3
|
+
require_relative '../../app/core'
|
|
4
|
+
require_relative '../../processor/main'
|
|
5
|
+
require_relative '../../processor/command/exit'
|
|
6
|
+
require_relative '../../processor/command/base/subcmd'
|
|
7
|
+
|
|
8
|
+
# Mock debugger stub. FIXME: put in comment helper routine.
|
|
9
|
+
class Trepan
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
$errors = []
|
|
13
|
+
class TestBaseCommandHelp < Test::Unit::TestCase
|
|
14
|
+
|
|
15
|
+
def setup
|
|
16
|
+
$errors = []
|
|
17
|
+
$msgs = []
|
|
18
|
+
@dbg = Trepan.new
|
|
19
|
+
@core = Trepan::Core.new(@dbg)
|
|
20
|
+
@cmdproc = @core.processor = Trepan::CmdProcessor.new(@core)
|
|
21
|
+
@cmds = @cmdproc.instance_variable_get('@commands')
|
|
22
|
+
@exit_cmd = @cmds['exit']
|
|
23
|
+
@exit_subcmd = Trepan::Subcommand.new(@exit_cmd)
|
|
24
|
+
def @exit_subcmd.msg(message)
|
|
25
|
+
$msgs << message
|
|
26
|
+
end
|
|
27
|
+
def @exit_subcmd.errmsg(message)
|
|
28
|
+
$errors << message
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def test_base_subcommand
|
|
33
|
+
assert @exit_subcmd
|
|
34
|
+
assert_raises RuntimeError do
|
|
35
|
+
@exit_subcmd.run
|
|
36
|
+
end
|
|
37
|
+
assert_equal([], $errors)
|
|
38
|
+
@exit_subcmd.run_set_int('', 'testing 1 2 3')
|
|
39
|
+
assert_equal(1, $errors.size)
|
|
40
|
+
assert_equal(Fixnum, @exit_subcmd.settings[:maxwidth].class)
|
|
41
|
+
@cmds.each do |cmd_name, cmd_obj|
|
|
42
|
+
next unless cmd_obj.is_a?(Trepan::SubcommandMgr)
|
|
43
|
+
cmd_obj.subcmds.subcmds.each do |subcmd_name, subcmd_obj|
|
|
44
|
+
%w(HELP NAME PREFIX).each do |attr|
|
|
45
|
+
assert_equal(true, subcmd_obj.class.constants.member?(attr.to_sym),
|
|
46
|
+
"Constant #{attr} should be defined in \"#{cmd_obj.name} #{subcmd_obj.name}\"")
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def test_show_on_off
|
|
54
|
+
assert_equal('on', @exit_subcmd.show_onoff(true))
|
|
55
|
+
assert_equal('off', @exit_subcmd.show_onoff(false))
|
|
56
|
+
assert_equal('unset', @exit_subcmd.show_onoff(nil))
|
|
57
|
+
assert_equal('??', @exit_subcmd.show_onoff(5))
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require 'test/unit'
|
|
3
|
+
require 'rbconfig'
|
|
4
|
+
load File.join(File.dirname(__FILE__), %w(.. .. bin trepan))
|
|
5
|
+
|
|
6
|
+
# Test bin/trepan Module methods
|
|
7
|
+
class TestBinTrepan < Test::Unit::TestCase
|
|
8
|
+
|
|
9
|
+
include Trepanning
|
|
10
|
+
|
|
11
|
+
def test_ruby_path
|
|
12
|
+
rb_path = ruby_path
|
|
13
|
+
assert_equal(true, File.executable?(rb_path),
|
|
14
|
+
"#{rb_path} should be an executable Ruby interpreter")
|
|
15
|
+
|
|
16
|
+
# Let us test that we get *exactly* the same configuration as we
|
|
17
|
+
# have in this. I'm a ball buster.
|
|
18
|
+
cmd = "#{rb_path} -rrbconfig -e 'puts Marshal.dump(RbConfig::CONFIG)'"
|
|
19
|
+
rb_config = Marshal.load(`#{cmd}`)
|
|
20
|
+
assert_equal(RbConfig::CONFIG, rb_config,
|
|
21
|
+
"#{rb_path} config doesn't match got:
|
|
22
|
+
#{rb_config.pretty_inspect}
|
|
23
|
+
expected:
|
|
24
|
+
#{RbConfig::CONFIG.pretty_inspect}
|
|
25
|
+
")
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def test_whence_file
|
|
29
|
+
abs_path_me = File.expand_path(__FILE__)
|
|
30
|
+
assert_equal(abs_path_me, whence_file(abs_path_me),
|
|
31
|
+
"whence_file should have just returned #{abs_path_me}")
|
|
32
|
+
|
|
33
|
+
basename_me = File.basename(__FILE__)
|
|
34
|
+
dirname_me = File.dirname(__FILE__)
|
|
35
|
+
|
|
36
|
+
# Add my directory onto the beginning of PATH
|
|
37
|
+
path_dirs = ENV['PATH'].split(File::PATH_SEPARATOR)
|
|
38
|
+
path_dirs.unshift(dirname_me)
|
|
39
|
+
ENV['PATH'] = path_dirs.join(File::PATH_SEPARATOR)
|
|
40
|
+
|
|
41
|
+
assert_equal(File.join(dirname_me, basename_me),
|
|
42
|
+
whence_file(basename_me),
|
|
43
|
+
"whence_file should have found me")
|
|
44
|
+
# Restore old path
|
|
45
|
+
path_dirs.shift
|
|
46
|
+
ENV['PATH'] = path_dirs.join(File::PATH_SEPARATOR)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require 'test/unit'
|
|
3
|
+
require_relative 'cmd-helper'
|
|
4
|
+
require_relative '../../processor/command/alias'
|
|
5
|
+
require_relative '../../processor/command/unalias'
|
|
6
|
+
|
|
7
|
+
# Test commands alias and unalias
|
|
8
|
+
class TestCommandAliasUnalias < Test::Unit::TestCase
|
|
9
|
+
|
|
10
|
+
include UnitHelper
|
|
11
|
+
def setup
|
|
12
|
+
common_setup
|
|
13
|
+
@name = File.basename(__FILE__, '.rb').split(/-/)[2]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def check_alias(should_not_have, cmd_name, *args)
|
|
17
|
+
@cmdproc.instance_variable_set('@msgs', [])
|
|
18
|
+
@cmdproc.instance_variable_set('@errmsgs', [])
|
|
19
|
+
arg_str = args.join(' ')
|
|
20
|
+
my_cmd = @cmds[cmd_name]
|
|
21
|
+
my_cmd.run([cmd_name] + args)
|
|
22
|
+
shoulda = should_not_have ? ['no ', ''] : ['', 'no ']
|
|
23
|
+
msgs = @cmdproc.instance_variable_get('@msgs')
|
|
24
|
+
errmsgs = @cmdproc.instance_variable_get('@errmsgs')
|
|
25
|
+
assert_equal(should_not_have, msgs.empty?,
|
|
26
|
+
"Expecting %s%s for #{arg_str}.\n Got #{msgs}" %
|
|
27
|
+
[shoulda[0], cmd_name])
|
|
28
|
+
assert_equal(!should_not_have, errmsgs.empty?,
|
|
29
|
+
"Expecting %serror for #{arg_str}.\n Got #{errmsgs}" %
|
|
30
|
+
shoulda[1])
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def alias_defined?(alias_name)
|
|
34
|
+
@cmdproc.aliases.member?(alias_name)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def test_alias_command
|
|
38
|
+
|
|
39
|
+
assert_equal(false, @cmdproc.aliases.empty?,
|
|
40
|
+
'There should be some aliases defined')
|
|
41
|
+
|
|
42
|
+
assert_equal(false, alias_defined?('ki'))
|
|
43
|
+
check_alias(false, 'alias', 'ki', 'kill')
|
|
44
|
+
assert_equal(true, alias_defined?('ki'))
|
|
45
|
+
check_alias(false, 'unalias', 'ki')
|
|
46
|
+
assert_equal(false, alias_defined?('ki'))
|
|
47
|
+
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require 'test/unit'
|
|
3
|
+
require 'thread_frame'
|
|
4
|
+
require_relative 'cmd-helper'
|
|
5
|
+
|
|
6
|
+
class TestCommandBreak < Test::Unit::TestCase
|
|
7
|
+
|
|
8
|
+
include UnitHelper
|
|
9
|
+
def setup
|
|
10
|
+
common_setup
|
|
11
|
+
@name = File.basename(__FILE__, '.rb').split(/-/)[2]
|
|
12
|
+
@my_cmd = @cmds[@name]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def test_basic
|
|
16
|
+
tf = RubyVM::ThreadFrame.current
|
|
17
|
+
@cmdproc.frame_setup(tf)
|
|
18
|
+
[
|
|
19
|
+
[@name, __LINE__.to_s],
|
|
20
|
+
].each_with_index do |args, i|
|
|
21
|
+
@my_cmd.run(args)
|
|
22
|
+
assert_equal(true, @cmdproc.errmsgs.empty?, @cmdproc.errmsgs)
|
|
23
|
+
assert_equal(0,
|
|
24
|
+
@cmdproc.msgs[0] =~ /^Breakpoint \d+ set at line \d+ in file #{__FILE__},\n\tVM offset \d+ of instruction sequence \"test_basic\"\.$/,
|
|
25
|
+
@cmdproc.msgs[0])
|
|
26
|
+
reset_cmdproc_vars
|
|
27
|
+
end
|
|
28
|
+
pc_offset = tf.pc_offset
|
|
29
|
+
[[@name],
|
|
30
|
+
[@name, "O#{pc_offset}"],
|
|
31
|
+
].each_with_index do |args, i|
|
|
32
|
+
@my_cmd.run(args)
|
|
33
|
+
assert_equal(true, @cmdproc.errmsgs.empty?, @cmdproc.errmsgs)
|
|
34
|
+
assert_equal(0,
|
|
35
|
+
@cmdproc.msgs[0] =~ /^Breakpoint \d+ set at VM offset \d+ of instruction sequence \"test_basic\",\n\tline \d+ in file .+\.$/,
|
|
36
|
+
@cmdproc.msgs[0])
|
|
37
|
+
reset_cmdproc_vars
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def foo
|
|
41
|
+
5
|
|
42
|
+
end
|
|
43
|
+
[[@name, 'foo', (__LINE__-3).to_s]].each_with_index do |args, i|
|
|
44
|
+
@my_cmd.run(args)
|
|
45
|
+
assert_equal(true, @cmdproc.errmsgs.empty?,
|
|
46
|
+
@cmdproc.errmsgs)
|
|
47
|
+
assert_equal(0,
|
|
48
|
+
@cmdproc.msgs[0] =~ /^Breakpoint \d+ set at line \d+ in file #{__FILE__},\n\tVM offset \d+ of instruction sequence \"foo\"\.$/,
|
|
49
|
+
@cmdproc.msgs[0])
|
|
50
|
+
reset_cmdproc_vars
|
|
51
|
+
end
|
|
52
|
+
[[@name, 'foo']].each_with_index do |args, i|
|
|
53
|
+
@my_cmd.run(args)
|
|
54
|
+
assert_equal(true, @cmdproc.errmsgs.empty?,
|
|
55
|
+
@cmdproc.errmsgs)
|
|
56
|
+
assert_equal(0,
|
|
57
|
+
@cmdproc.msgs[0] =~ /Breakpoint \d+ set at line \d+ in file #{__FILE__},\n\tVM offset \d+/,
|
|
58
|
+
@cmdproc.msgs[0])
|
|
59
|
+
reset_cmdproc_vars
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Test setting a breakpoint at a line that can only be found using
|
|
64
|
+
# the parent instruction sequence, i.e. the line is not in the
|
|
65
|
+
# current instruction sequence.
|
|
66
|
+
def test_parent_breakpoint
|
|
67
|
+
xx = 5 # This is the line we set the breakpoint for.
|
|
68
|
+
1.times do
|
|
69
|
+
tf = RubyVM::ThreadFrame.current
|
|
70
|
+
@cmdproc.frame_setup(tf)
|
|
71
|
+
@my_cmd.run([@name, (__LINE__-4).to_s])
|
|
72
|
+
assert_equal(true, @cmdproc.errmsgs.empty?, @cmdproc.errmsgs)
|
|
73
|
+
assert_equal(0,
|
|
74
|
+
@cmdproc.msgs[0] =~ /^Breakpoint \d+ set at line \d+ in file .+\n\tVM offset \d+ of instruction sequence \"test_parent_breakpoint\"\.$/,
|
|
75
|
+
@cmdproc.msgs[0])
|
|
76
|
+
reset_cmdproc_vars
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require 'test/unit'
|
|
3
|
+
require_relative 'cmd-helper'
|
|
4
|
+
require_relative '../../app/breakpoint'
|
|
5
|
+
|
|
6
|
+
class TestCommandEnableDisable < Test::Unit::TestCase
|
|
7
|
+
|
|
8
|
+
include UnitHelper
|
|
9
|
+
def setup
|
|
10
|
+
Trepanning::Breakpoint::reset
|
|
11
|
+
common_setup
|
|
12
|
+
@break_cmd = @cmds['break']
|
|
13
|
+
@disable_cmd = @cmds['disable']
|
|
14
|
+
@enable_cmd = @cmds['enable']
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def test_basic
|
|
18
|
+
|
|
19
|
+
# Some simple errors in running enable/disable commands
|
|
20
|
+
[[@enable_cmd, ['enable', '1'], 0, 1],
|
|
21
|
+
[@disable_cmd, ['disable', '1'], 0, 1]].each do
|
|
22
|
+
|cmd, args, nmsgs, nerrs|
|
|
23
|
+
# No breakpoint number given
|
|
24
|
+
cmd.run(args[0..0])
|
|
25
|
+
assert_equal(nmsgs, @cmdproc.msgs.size,
|
|
26
|
+
"#{args} - msgs: #{@cmdproc.msgs.inspect}")
|
|
27
|
+
assert_equal(nerrs, @cmdproc.errmsgs.size,
|
|
28
|
+
"#{args} - errmsgs: #{@cmdproc.errmsgs.inspect}")
|
|
29
|
+
reset_cmdproc_vars
|
|
30
|
+
|
|
31
|
+
# Non-existent breakpoint
|
|
32
|
+
cmd.run(args)
|
|
33
|
+
assert_equal(true, @cmdproc.msgs.empty?)
|
|
34
|
+
assert_equal(1, @cmdproc.errmsgs.size)
|
|
35
|
+
reset_cmdproc_vars
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
require 'thread_frame'
|
|
39
|
+
tf = RubyVM::ThreadFrame.current
|
|
40
|
+
@cmdproc.frame_setup(tf)
|
|
41
|
+
pc_offset = tf.pc_offset
|
|
42
|
+
@break_cmd.run(['break'])
|
|
43
|
+
assert_equal(true, @cmdproc.errmsgs.empty?)
|
|
44
|
+
assert_equal(1, @cmdproc.msgs.size)
|
|
45
|
+
reset_cmdproc_vars
|
|
46
|
+
|
|
47
|
+
@disable_cmd.run(['disable', '1'])
|
|
48
|
+
assert_equal(0,
|
|
49
|
+
@cmdproc.msgs[0] =~ /^Breakpoint 1 disabled./,
|
|
50
|
+
@cmdproc.msgs)
|
|
51
|
+
reset_cmdproc_vars
|
|
52
|
+
|
|
53
|
+
@enable_cmd.run(['enable', '1'])
|
|
54
|
+
assert_equal(0,
|
|
55
|
+
@cmdproc.msgs[0] =~ /^Breakpoint 1 enabled./,
|
|
56
|
+
@cmdproc.msgs)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
end
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require 'test/unit'
|
|
3
|
+
require_relative 'cmd-helper'
|
|
4
|
+
require_relative '../../processor/command/help'
|
|
5
|
+
|
|
6
|
+
class TestCommandHelp < Test::Unit::TestCase
|
|
7
|
+
|
|
8
|
+
include UnitHelper
|
|
9
|
+
def setup
|
|
10
|
+
common_setup
|
|
11
|
+
@name = File.basename(__FILE__, '.rb').split(/-/)[2]
|
|
12
|
+
@my_cmd = @cmds[@name]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def check_help(should_not_have, *args)
|
|
16
|
+
@cmdproc.instance_variable_set('@msgs', [])
|
|
17
|
+
@cmdproc.instance_variable_set('@errmsgs', [])
|
|
18
|
+
arg_str = args.join(' ')
|
|
19
|
+
@my_cmd.run([@name] + args)
|
|
20
|
+
shoulda = should_not_have ? ['no ', ''] : ['', 'no ']
|
|
21
|
+
msgs = @cmdproc.instance_variable_get('@msgs')
|
|
22
|
+
errmsgs = @cmdproc.instance_variable_get('@errmsgs')
|
|
23
|
+
assert_equal(should_not_have, msgs.empty?,
|
|
24
|
+
"Expecting %shelp for #{arg_str}.\n Got #{msgs}" %
|
|
25
|
+
shoulda[0])
|
|
26
|
+
assert_equal(!should_not_have, errmsgs.empty?,
|
|
27
|
+
"Expecting %serror for #{arg_str}.\n Got #{errmsgs}" %
|
|
28
|
+
shoulda[1])
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def test_help_command
|
|
32
|
+
|
|
33
|
+
# Test we can run 'help *cmd* for each command
|
|
34
|
+
@cmds.keys.each do |cmd_name|
|
|
35
|
+
check_help(false, cmd_name)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Test we can run 'help *alias* for each alias
|
|
39
|
+
@cmdproc.aliases.keys.each do |alias_name|
|
|
40
|
+
check_help(false, alias_name)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# double-check specific commands and aliases
|
|
44
|
+
%w(step n help).each do |cmd_pat|
|
|
45
|
+
check_help(false, cmd_pat)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Test patterns
|
|
49
|
+
%w(* s.* ste).each do |cmd_pat|
|
|
50
|
+
check_help(false, cmd_pat)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Test categories
|
|
54
|
+
%w(running stack).each do |cmd_pat|
|
|
55
|
+
check_help(false, cmd_pat)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Test sub help and subhelp patterns
|
|
59
|
+
[%w(info file), %w(show *)].each do |args|
|
|
60
|
+
check_help(false, args)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Test invalid commands
|
|
64
|
+
%w(bogus abcd.*).each do |cmd_pat|
|
|
65
|
+
check_help(true, cmd_pat)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# invalid help subcommands
|
|
69
|
+
[%w(info fdafds), %w(fedafdsa *)].each do |args|
|
|
70
|
+
check_help(true, *args)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# screwball error
|
|
74
|
+
check_help(true, '["info",')
|
|
75
|
+
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# FIXME: Do better than this.
|
|
79
|
+
def check_subcmd_help(cmd_name, subcmd, *args)
|
|
80
|
+
def subcmd.msg(mess)
|
|
81
|
+
@msgs << mess
|
|
82
|
+
end
|
|
83
|
+
subcmd.instance_variable_set('@msgs', [])
|
|
84
|
+
subcmd.instance_variable_set('@errmsgs', [])
|
|
85
|
+
subcmd.help(cmd_name)
|
|
86
|
+
assert subcmd.instance_variable_get('@msgs')
|
|
87
|
+
# subcmd.help
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def test_help_subcommand
|
|
91
|
+
# Get list of commands with subcmds
|
|
92
|
+
cmd_names = @cmds.values.map do |c|
|
|
93
|
+
c.instance_variable_defined?(:@subcmds) ? c.name : nil
|
|
94
|
+
end.compact
|
|
95
|
+
cmd_names.each do |cmd_name|
|
|
96
|
+
check_subcmd_help(cmd_name, @cmds[cmd_name].subcmds)
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
end
|