rbx-trepanning 0.2.0-universal-rubinius-2.0 → 0.2.1-universal-rubinius-2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +2 -1
- data/.travis.yml +4 -0
- data/ChangeLog +119 -1
- data/Gemfile +16 -0
- data/NEWS +15 -8
- data/README.md +72 -0
- data/Rakefile +16 -13
- data/app/cmd_parse.kpeg +38 -40
- data/app/cmd_parse.rb +25 -20
- data/app/cmd_parser.rb +1030 -1036
- data/app/complete.rb +12 -12
- data/app/default.rb +6 -5
- data/app/options.rb +1 -1
- data/app/util.rb +17 -10
- data/lib/trepanning.rb +0 -1
- data/processor.rb +32 -32
- data/processor/command.rb +32 -13
- data/processor/command/base/submgr.rb +22 -14
- data/processor/command/base/subsubcmd.rb +11 -13
- data/processor/command/base/subsubmgr.rb +38 -19
- data/processor/command/disassemble.rb +11 -11
- data/processor/command/help.rb +24 -24
- data/processor/command/shell.rb +17 -17
- data/processor/help.rb +9 -11
- data/processor/load_cmds.rb +26 -16
- data/processor/mock.rb +8 -9
- data/processor/subcmd.rb +12 -12
- data/test/functional/fn_helper.rb +8 -7
- data/test/functional/test-recursive-bt.rb +26 -15
- data/test/integration/test-quit.rb +8 -2
- data/test/unit/cmd-helper.rb +2 -2
- data/test/unit/test-base-subcmd.rb +14 -3
- data/test/unit/test-io-tcpserver.rb +10 -5
- data/test/unit/test-proc-validate.rb +4 -4
- metadata +116 -110
- data/README.textile +0 -34
data/processor/command/shell.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2010,
|
1
|
+
# Copyright (C) 2010-2011, 2013 Rocky Bernstein <rockyb@rubyforge.net>
|
2
2
|
require 'irb'
|
3
3
|
require 'rubygems'; require 'require_relative'
|
4
4
|
require_relative '../command'
|
@@ -13,10 +13,10 @@ class Trepan::Command::IRBCommand < Trepan::Command
|
|
13
13
|
starts an Interactive Ruby (IRB) session.
|
14
14
|
|
15
15
|
If -d is added you can get access to debugger frame the global variables
|
16
|
-
$trepan_frame and $trepan_cmdproc.
|
16
|
+
$trepan_frame and $trepan_cmdproc.
|
17
17
|
|
18
|
-
#{NAME} is extended with methods 'cont', 'ne', and, 'q', 'step' which
|
19
|
-
run the corresponding debugger commands 'continue', 'next', 'exit' and 'step'.
|
18
|
+
#{NAME} is extended with methods 'cont', 'ne', and, 'q', 'step' which
|
19
|
+
run the corresponding debugger commands 'continue', 'next', 'exit' and 'step'.
|
20
20
|
|
21
21
|
To issue a debugger command, inside #{NAME} nested inside a debugger use
|
22
22
|
'dbgr'. For example:
|
@@ -43,7 +43,7 @@ Here then is a loop to query VM stack values:
|
|
43
43
|
|
44
44
|
# This method runs the command
|
45
45
|
def run(args)
|
46
|
-
add_debugging =
|
46
|
+
add_debugging =
|
47
47
|
if args.size > 1
|
48
48
|
'-d' == args[1]
|
49
49
|
else
|
@@ -59,7 +59,7 @@ Here then is a loop to query VM stack values:
|
|
59
59
|
throw :IRB_EXIT, :cont if $trepan_in_irb
|
60
60
|
end
|
61
61
|
|
62
|
-
$trepan = @proc.dbgr
|
62
|
+
$trepan = @proc.dbgr
|
63
63
|
if add_debugging
|
64
64
|
$trepan_cmdproc = @proc
|
65
65
|
$trepan_frame = @proc.frame
|
@@ -72,32 +72,32 @@ Here then is a loop to query VM stack values:
|
|
72
72
|
:RC => true}
|
73
73
|
|
74
74
|
# ?? Should we set GNU readline to what we have,
|
75
|
-
# or let IRB make its own determination?
|
75
|
+
# or let IRB make its own determination?
|
76
76
|
|
77
|
-
# Save the Readline history and set the Readline completion function
|
78
|
-
# to be IRB's function
|
79
|
-
if Trepan::GNU_readline?
|
77
|
+
# Save the Readline history and set the Readline completion function
|
78
|
+
# to be IRB's function
|
79
|
+
if Trepan::GNU_readline?
|
80
80
|
@proc.intf.save_history if @proc.intf.respond_to?(:save_history)
|
81
81
|
require 'irb/completion'
|
82
82
|
Readline.completion_proc = IRB::InputCompletor::CompletionProc
|
83
83
|
end
|
84
84
|
|
85
|
-
# And just when you thought, we'd never get around to
|
85
|
+
# And just when you thought, we'd never get around to
|
86
86
|
# actually running irb...
|
87
87
|
cont = IRB.start_session(@proc.frame.binding, @proc, conf)
|
88
88
|
trap('SIGINT', save_trap) # Restore our old interrupt function.
|
89
89
|
|
90
|
-
# Restore the debuggers' Readline history and the Readline completion
|
90
|
+
# Restore the debuggers' Readline history and the Readline completion
|
91
91
|
# function
|
92
92
|
if Trepan::GNU_readline? && @proc.dbgr.completion_proc
|
93
93
|
@proc.intf.read_history if @proc.intf.respond_to?(:read_history)
|
94
|
-
Readline.completion_proc = @proc.dbgr.completion_proc
|
94
|
+
Readline.completion_proc = @proc.dbgr.completion_proc
|
95
95
|
end
|
96
96
|
|
97
97
|
# Respect any backtrace limit set in irb.
|
98
98
|
back_trace_limit = IRB.CurrentContext.back_trace_limit
|
99
99
|
if settings[:maxstack] != back_trace_limit
|
100
|
-
msg("\nSetting debugger's BACK_TRACE_LIMIT (%d) to match irb's last setting (%d)" %
|
100
|
+
msg("\nSetting debugger's BACK_TRACE_LIMIT (%d) to match irb's last setting (%d)" %
|
101
101
|
[settings[:maxstack], back_trace_limit])
|
102
102
|
settings[:maxstack]= IRB.CurrentContext.back_trace_limit
|
103
103
|
end
|
@@ -106,13 +106,13 @@ Here then is a loop to query VM stack values:
|
|
106
106
|
when :continue
|
107
107
|
@proc.continue
|
108
108
|
when :finish
|
109
|
-
@proc.finish
|
109
|
+
@proc.finish
|
110
110
|
when :next
|
111
|
-
@proc.step
|
111
|
+
@proc.step('next', 1, {})
|
112
112
|
when :quit
|
113
113
|
@proc.quit
|
114
114
|
when :step
|
115
|
-
@proc.step
|
115
|
+
@proc.step('step', 1, {})
|
116
116
|
else
|
117
117
|
@proc.print_location
|
118
118
|
end
|
data/processor/help.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2010,
|
1
|
+
# Copyright (C) 2010-2011, 2013 Rocky Bernstein <rockyb@rubyforge.net>
|
2
2
|
|
3
3
|
class Trepan
|
4
4
|
# class SubHelp
|
@@ -9,7 +9,7 @@ class Trepan
|
|
9
9
|
# end
|
10
10
|
|
11
11
|
# def load_sub_help_files(dir)
|
12
|
-
# Dir.glob(dir, '*.txt').each do |txt|
|
12
|
+
# Dir.glob(dir, '*.txt').each do |txt|
|
13
13
|
# basename = File.basename(txt, '.txt')
|
14
14
|
# @list << basename
|
15
15
|
# end
|
@@ -33,16 +33,14 @@ class Trepan
|
|
33
33
|
# The below was the simplest way I could find to do this since
|
34
34
|
# we are the super class but want to set the subclass's constant.
|
35
35
|
# defined? didn't seem to work here.
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
end
|
41
|
-
|
36
|
+
short_help = get_const(self.class, 'SHORT_HELP')
|
37
|
+
short_help = get_const(self.class, 'HELP') unless short_help
|
38
|
+
short_help = short_help.split("\n")[0].chomp('.')
|
39
|
+
|
42
40
|
' %-12s -- %s' %
|
43
|
-
[abbrev_stringify(obj_const(subcmd, :NAME),
|
41
|
+
[abbrev_stringify(obj_const(subcmd, :NAME),
|
44
42
|
obj_const(subcmd, :MIN_ABBREV)),
|
45
|
-
|
43
|
+
short_help]
|
46
44
|
end
|
47
45
|
|
48
46
|
# We were given cmd without a subcommand; cmd is something
|
@@ -77,7 +75,7 @@ Long description goes here.'
|
|
77
75
|
MIN_ABBREV = 1
|
78
76
|
NAME = File.basename(__FILE__)
|
79
77
|
def obj_const(obj, name)
|
80
|
-
obj.class.const_get(name)
|
78
|
+
obj.class.const_get(name)
|
81
79
|
end
|
82
80
|
def msg(mess)
|
83
81
|
puts mess
|
data/processor/load_cmds.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
# Copyright (C) 2010-2011, 2013 Rocky Bernstein <rockyb@rubyforge.net>
|
3
3
|
require 'tmpdir'
|
4
|
+
require 'redcard/rubinius'
|
4
5
|
|
5
6
|
# Part of Trepan::CmdProcess that loads up debugger commands from
|
6
7
|
# builtin and user directories.
|
@@ -33,6 +34,18 @@ class Trepan
|
|
33
34
|
end
|
34
35
|
end
|
35
36
|
|
37
|
+
def get_class_aliases(klass)
|
38
|
+
if RedCard.check '1.9' and
|
39
|
+
klass.constants.member?(:ALIASES)
|
40
|
+
klass.const_get(:ALIASES)
|
41
|
+
elsif RedCard.check '1.8' and
|
42
|
+
klass.constants.member?('ALIASES')
|
43
|
+
klass.const_get('ALIASES')
|
44
|
+
else
|
45
|
+
[]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
36
49
|
# Loads in debugger commands by require'ing each ruby file in the
|
37
50
|
# 'command' directory. Then a new instance of each class of the
|
38
51
|
# form Trepan::xxCommand is added to @commands and that array
|
@@ -63,12 +76,11 @@ class Trepan
|
|
63
76
|
klass = Trepan::Command.const_get(name)
|
64
77
|
cmd = klass.send(:new, self)
|
65
78
|
|
79
|
+
cmd_name = klass.const_get(:NAME)
|
80
|
+
|
66
81
|
# Add to list of commands and aliases.
|
67
82
|
cmd_name = klass.const_get(:NAME)
|
68
|
-
|
69
|
-
aliases= klass.const_get('ALIASES')
|
70
|
-
aliases.each {|a| @aliases[a] = cmd_name}
|
71
|
-
end
|
83
|
+
get_class_aliases(klass).each {|a| @aliases[a] = cmd_name}
|
72
84
|
@commands[cmd_name] = cmd
|
73
85
|
end
|
74
86
|
end
|
@@ -83,10 +95,7 @@ class Trepan
|
|
83
95
|
|
84
96
|
# Add to list of commands and aliases.
|
85
97
|
cmd_name = klass.const_get(:NAME)
|
86
|
-
|
87
|
-
aliases= klass.const_get(:ALIASES)
|
88
|
-
aliases.each {|a| @aliases[a] = cmd_name}
|
89
|
-
end
|
98
|
+
get_class_aliases.each {|a| @aliases[a] = cmd_name}
|
90
99
|
@commands[cmd_name] = cmd
|
91
100
|
end
|
92
101
|
|
@@ -227,14 +236,6 @@ if __FILE__ == $0
|
|
227
236
|
end
|
228
237
|
|
229
238
|
cmdproc = Trepan::CmdProcessor.new(nil)
|
230
|
-
cmddir = File.join(File.dirname(__FILE__), 'command')
|
231
|
-
cmdproc.instance_variable_set('@settings', {})
|
232
|
-
cmdproc.load_cmds_initialize
|
233
|
-
require 'columnize'
|
234
|
-
puts Columnize.columnize(cmdproc.commands.keys.sort)
|
235
|
-
puts '=' * 20
|
236
|
-
puts Columnize.columnize(cmdproc.aliases.keys.sort)
|
237
|
-
puts '=' * 20
|
238
239
|
|
239
240
|
def cmdproc.errmsg(mess)
|
240
241
|
puts "** #{mess}"
|
@@ -244,6 +245,15 @@ if __FILE__ == $0
|
|
244
245
|
puts mess
|
245
246
|
end
|
246
247
|
|
248
|
+
cmddir = File.join(File.dirname(__FILE__), 'command')
|
249
|
+
cmdproc.instance_variable_set('@settings', {})
|
250
|
+
cmdproc.load_cmds_initialize
|
251
|
+
require 'columnize'
|
252
|
+
puts Columnize.columnize(cmdproc.commands.keys.sort)
|
253
|
+
puts '=' * 20
|
254
|
+
puts Columnize.columnize(cmdproc.aliases.keys.sort)
|
255
|
+
puts '=' * 20
|
256
|
+
|
247
257
|
cmdproc.run_cmd('foo') # Invalid - not an Array
|
248
258
|
cmdproc.run_cmd([]) # Invalid - empty Array
|
249
259
|
cmdproc.run_cmd(['list', 5]) # Invalid - nonstring arg
|
data/processor/mock.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2010,
|
1
|
+
# Copyright (C) 2010-2011, 2013 Rocky Bernstein <rockyb@rubyforge.net>
|
2
2
|
# Mock setup for commands.
|
3
3
|
require 'rubygems'; require 'require_relative'
|
4
4
|
|
@@ -18,14 +18,14 @@ module MockDebugger
|
|
18
18
|
attr_accessor :intf # The way the outside world interfaces with us.
|
19
19
|
attr_reader :initial_dir # String. Current directory when program
|
20
20
|
# started. Used in restart program.
|
21
|
-
attr_accessor :restart_argv # How to restart us, empty or nil.
|
21
|
+
attr_accessor :restart_argv # How to restart us, empty or nil.
|
22
22
|
# Note restart[0] is typically $0.
|
23
23
|
attr_reader :settings # Hash[:symbol] of things you can configure
|
24
24
|
attr_accessor :processor
|
25
25
|
|
26
26
|
# FIXME: move more stuff of here and into Trepan::CmdProcessor
|
27
27
|
# These below should go into Trepan::CmdProcessor.
|
28
|
-
attr_reader :cmd_argstr, :cmd_name, :vm_locations, :current_frame,
|
28
|
+
attr_reader :cmd_argstr, :cmd_name, :vm_locations, :current_frame,
|
29
29
|
:debugee_thread, :completion_proc
|
30
30
|
|
31
31
|
def initialize(settings={:start_frame=>1})
|
@@ -45,7 +45,7 @@ module MockDebugger
|
|
45
45
|
@completion_proc = Proc.new{|str| str}
|
46
46
|
|
47
47
|
# Don't allow user commands in mocks.
|
48
|
-
## @core.processor.settings[:user_cmd_dir] = nil
|
48
|
+
## @core.processor.settings[:user_cmd_dir] = nil
|
49
49
|
|
50
50
|
end
|
51
51
|
|
@@ -54,7 +54,7 @@ module MockDebugger
|
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
57
|
-
# Common Mock debugger setup
|
57
|
+
# Common Mock debugger setup
|
58
58
|
def setup(name=nil, show_constants=true)
|
59
59
|
unless name
|
60
60
|
loc = Rubinius::VM.backtrace(1, true)[0]
|
@@ -72,7 +72,7 @@ module MockDebugger
|
|
72
72
|
cmdproc = Trepan::CmdProcessor.new(dbgr)
|
73
73
|
cmdproc.frame = dbgr.frame(0)
|
74
74
|
dbgr.processor = cmdproc
|
75
|
-
|
75
|
+
|
76
76
|
cmdproc.load_cmds_initialize
|
77
77
|
cmds = cmdproc.commands
|
78
78
|
cmd = cmds[name]
|
@@ -116,9 +116,8 @@ module MockDebugger
|
|
116
116
|
module_function :subsub_setup
|
117
117
|
|
118
118
|
def show_special_class_constants(cmd)
|
119
|
-
puts 'ALIASES: %s' % [cmd.
|
120
|
-
|
121
|
-
%w(CATEGORY MIN_ARGS MAX_ARGS
|
119
|
+
puts 'ALIASES: %s' % [cmd.proc.get_class_aliases(cmd.class).inspect]
|
120
|
+
%w(CATEGORY MIN_ARGS MAX_ARGS
|
122
121
|
NAME NEED_STACK SHORT_HELP).each do |name|
|
123
122
|
puts '%s: %s' % [name, cmd.class.const_get(name).inspect]
|
124
123
|
end
|
data/processor/subcmd.rb
CHANGED
@@ -12,13 +12,13 @@ class Trepan
|
|
12
12
|
@subcmds = {}
|
13
13
|
@cmdlist = []
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
# Find subcmd in self.subcmds
|
17
17
|
def lookup(subcmd_prefix, use_regexp=true)
|
18
|
-
compare =
|
18
|
+
compare =
|
19
19
|
if !@cmd.settings[:abbrev]
|
20
20
|
lambda{|name| name.to_s == subcmd_prefix}
|
21
|
-
elsif use_regexp
|
21
|
+
elsif use_regexp
|
22
22
|
lambda{|name| name.to_s =~ /^#{subcmd_prefix}/}
|
23
23
|
else
|
24
24
|
lambda{|name| 0 == name.to_s.index(subcmd_prefix)}
|
@@ -46,7 +46,7 @@ class Trepan
|
|
46
46
|
prefix = ''
|
47
47
|
end
|
48
48
|
if entry.respond_to?(:short_help)
|
49
|
-
prefix += ' -- ' if prefix
|
49
|
+
prefix += ' -- ' if prefix
|
50
50
|
@proc.msg(prefix + entry.short_help)
|
51
51
|
end
|
52
52
|
else
|
@@ -89,23 +89,23 @@ if __FILE__ == $0
|
|
89
89
|
require_relative 'command'
|
90
90
|
|
91
91
|
class Trepan::TestCommand < Trepan::Command
|
92
|
-
|
92
|
+
|
93
93
|
HELP = 'Help string string for testing'
|
94
94
|
CATEGORY = 'data'
|
95
95
|
MIN_ARGS = 0
|
96
96
|
MAX_ARGS = 5
|
97
97
|
NAME_ALIASES = %w(test)
|
98
|
-
|
98
|
+
|
99
99
|
def initialize(proc); @proc = proc end
|
100
|
-
|
100
|
+
|
101
101
|
def run(args); puts 'test command run' end
|
102
102
|
end
|
103
|
-
|
103
|
+
|
104
104
|
class TestTestingSubcommand
|
105
105
|
HELP = 'Help string for test testing subcommand'
|
106
|
-
|
106
|
+
|
107
107
|
def initialize; @name = 'testing' end
|
108
|
-
|
108
|
+
|
109
109
|
SHORT_HELP = 'This is short help for test testing'
|
110
110
|
MIN_ABREV = 4
|
111
111
|
IN_LIST = true
|
@@ -119,12 +119,12 @@ if __FILE__ == $0
|
|
119
119
|
# testcmdMgr = Subcmd.new('test', testcmd)
|
120
120
|
# testsub = TestTestingSubcommand.new
|
121
121
|
# testcmdMgr.add(testsub)
|
122
|
-
|
122
|
+
|
123
123
|
# %w(tes test testing testing1).each do |prefix|
|
124
124
|
# x = testcmdMgr.lookup(prefix)
|
125
125
|
# puts x ? x.name : 'Non'
|
126
126
|
# end
|
127
|
-
|
127
|
+
|
128
128
|
# testcmdMgr.short_help(testcmd, 'testing')
|
129
129
|
# testcmdMgr.short_help(testcmd, 'test', true)
|
130
130
|
# testcmdMgr.short_help(testcmd, 'tes')
|
@@ -32,10 +32,11 @@ module FnTestHelper
|
|
32
32
|
Rubinius::VM.backtrace(0)[1].line
|
33
33
|
end
|
34
34
|
|
35
|
-
def compare_output(right, d, debugger_cmds)
|
35
|
+
def compare_output(right, d, debugger_cmds, filter_fn = nil)
|
36
36
|
# require_relative '../../lib/trepanning'
|
37
37
|
# Trepan.debug(:set_restart => true)
|
38
38
|
got = filter_line_cmd(d.intf[-1].output.output)
|
39
|
+
got = send(:filter_fn, got) if filter_fn
|
39
40
|
if got != right
|
40
41
|
got.each_with_index do |got_line, i|
|
41
42
|
if i < right.size and got_line != right[i]
|
@@ -65,22 +66,22 @@ module FnTestHelper
|
|
65
66
|
s =~ TREPAN_PROMPT ? nil : s
|
66
67
|
end.compact unless show_prompt
|
67
68
|
|
68
|
-
# Remove debugger location lines.
|
69
|
-
# For example:
|
69
|
+
# Remove debugger location lines.
|
70
|
+
# For example:
|
70
71
|
# -- (/src/external-vcs/trepan/tmp/gcd.rb:4 @21)
|
71
72
|
# becomes:
|
72
|
-
# --
|
73
|
+
# --
|
73
74
|
a2 = a.map do |s|
|
74
75
|
s =~ TREPAN_LOC ? s.gsub(/\(.+:\d+( @\d+)?\)\n/, '').chomp : s.chomp
|
75
76
|
end
|
76
77
|
|
77
|
-
# Canonicalize breakpoint messages.
|
78
|
-
# For example:
|
78
|
+
# Canonicalize breakpoint messages.
|
79
|
+
# For example:
|
79
80
|
# Set breakpoint 1: test/functional/test-tbreak.rb:10 (@0)
|
80
81
|
# becomes :
|
81
82
|
# Set breakpoint 1: foo.rb:55 (@3)
|
82
83
|
a3 = a2.map do |s|
|
83
|
-
s.gsub(/^Set (temporary )?breakpoint (\d+): .+:(\d+) \(@\d+\)/,
|
84
|
+
s.gsub(/^Set (temporary )?breakpoint (\d+): .+:(\d+) \(@\d+\)/,
|
84
85
|
'Set \1breakpoint \2: foo.rb:55 (@3)')
|
85
86
|
end
|
86
87
|
return a3
|
@@ -7,6 +7,16 @@ class TestRecursiveBt < Test::Unit::TestCase
|
|
7
7
|
|
8
8
|
include FnTestHelper
|
9
9
|
|
10
|
+
def filter_fn(a)
|
11
|
+
a.map { |line|
|
12
|
+
if line =~ /#6 MiniTest::Unit::TestCase/
|
13
|
+
" #6 Test::Unit::TestCase(TestRecursiveBt)#run(result) at testcase.rb:78"
|
14
|
+
else
|
15
|
+
line
|
16
|
+
end
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
10
20
|
def test_recursive_backtrace
|
11
21
|
|
12
22
|
cmds = [
|
@@ -42,28 +52,28 @@ class TestRecursiveBt < Test::Unit::TestCase
|
|
42
52
|
z = factorial(5)
|
43
53
|
##############################
|
44
54
|
d.stop
|
45
|
-
out =
|
55
|
+
out =
|
46
56
|
["-- ",
|
47
57
|
"def factorial(n)",
|
48
58
|
"basename is on.",
|
49
59
|
"-- ",
|
50
60
|
"z = factorial(5)",
|
51
|
-
"--> #0 TestRecursiveBt#test_recursive_backtrace at test-recursive-bt.rb:
|
61
|
+
"--> #0 TestRecursiveBt#test_recursive_backtrace at test-recursive-bt.rb:52",
|
52
62
|
"(More stack frames follow...)",
|
53
63
|
"-> ",
|
54
64
|
"if n > 0",
|
55
65
|
"-- ",
|
56
66
|
"return n * factorial(n-1)",
|
57
|
-
"--> #0 TestRecursiveBt#factorial(n) at test-recursive-bt.rb:
|
58
|
-
" #1 TestRecursiveBt#test_recursive_backtrace at test-recursive-bt.rb:
|
67
|
+
"--> #0 TestRecursiveBt#factorial(n) at test-recursive-bt.rb:47",
|
68
|
+
" #1 TestRecursiveBt#test_recursive_backtrace at test-recursive-bt.rb:52",
|
59
69
|
"(More stack frames follow...)",
|
60
70
|
"-> ",
|
61
71
|
"if n > 0",
|
62
72
|
"-- ",
|
63
73
|
"return n * factorial(n-1)",
|
64
|
-
"--> #0 TestRecursiveBt#factorial(n) at test-recursive-bt.rb:
|
65
|
-
" #1 TestRecursiveBt#factorial(n) at test-recursive-bt.rb:
|
66
|
-
" #2 TestRecursiveBt#test_recursive_backtrace at test-recursive-bt.rb:
|
74
|
+
"--> #0 TestRecursiveBt#factorial(n) at test-recursive-bt.rb:47",
|
75
|
+
" #1 TestRecursiveBt#factorial(n) at test-recursive-bt.rb:47",
|
76
|
+
" #2 TestRecursiveBt#test_recursive_backtrace at test-recursive-bt.rb:52",
|
67
77
|
"(More stack frames follow...)",
|
68
78
|
"-> ",
|
69
79
|
"if n > 0",
|
@@ -71,10 +81,10 @@ class TestRecursiveBt < Test::Unit::TestCase
|
|
71
81
|
"return n * factorial(n-1)",
|
72
82
|
"-> ",
|
73
83
|
"if n > 0",
|
74
|
-
"--> #0 TestRecursiveBt#factorial(n) at test-recursive-bt.rb:
|
75
|
-
" #1 TestRecursiveBt#factorial(n) at test-recursive-bt.rb:
|
84
|
+
"--> #0 TestRecursiveBt#factorial(n) at test-recursive-bt.rb:46",
|
85
|
+
" #1 TestRecursiveBt#factorial(n) at test-recursive-bt.rb:47",
|
76
86
|
"... above line repeated 2 times",
|
77
|
-
" #4 TestRecursiveBt#test_recursive_backtrace at test-recursive-bt.rb:
|
87
|
+
" #4 TestRecursiveBt#test_recursive_backtrace at test-recursive-bt.rb:52",
|
78
88
|
"(More stack frames follow...)",
|
79
89
|
"-- ",
|
80
90
|
"return n * factorial(n-1)",
|
@@ -82,13 +92,14 @@ class TestRecursiveBt < Test::Unit::TestCase
|
|
82
92
|
"if n > 0",
|
83
93
|
"-- ",
|
84
94
|
"return n * factorial(n-1)",
|
85
|
-
"--> #0 TestRecursiveBt#factorial(n) at test-recursive-bt.rb:
|
86
|
-
" #1 TestRecursiveBt#factorial(n) at test-recursive-bt.rb:
|
95
|
+
"--> #0 TestRecursiveBt#factorial(n) at test-recursive-bt.rb:47",
|
96
|
+
" #1 TestRecursiveBt#factorial(n) at test-recursive-bt.rb:47",
|
87
97
|
"... above line repeated 3 times",
|
88
|
-
" #5 TestRecursiveBt#test_recursive_backtrace at test-recursive-bt.rb:
|
98
|
+
" #5 TestRecursiveBt#test_recursive_backtrace at test-recursive-bt.rb:52",
|
89
99
|
" #6 Test::Unit::TestCase(TestRecursiveBt)#run(result) at testcase.rb:78",
|
90
|
-
"(More stack frames follow...)"
|
91
|
-
|
100
|
+
"(More stack frames follow...)"
|
101
|
+
]
|
102
|
+
compare_output(out, d, cmds, :filter_fn)
|
92
103
|
|
93
104
|
end
|
94
105
|
end
|