ruby-prof 0.18.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +44 -1
  3. data/LICENSE +2 -2
  4. data/README.rdoc +1 -483
  5. data/Rakefile +3 -6
  6. data/bin/ruby-prof +111 -128
  7. data/ext/ruby_prof/extconf.rb +6 -38
  8. data/ext/ruby_prof/rp_aggregate_call_tree.c +41 -0
  9. data/ext/ruby_prof/rp_aggregate_call_tree.h +13 -0
  10. data/ext/ruby_prof/rp_allocation.c +259 -0
  11. data/ext/ruby_prof/rp_allocation.h +31 -0
  12. data/ext/ruby_prof/rp_call_tree.c +353 -0
  13. data/ext/ruby_prof/rp_call_tree.h +43 -0
  14. data/ext/ruby_prof/rp_call_trees.c +266 -0
  15. data/ext/ruby_prof/rp_call_trees.h +29 -0
  16. data/ext/ruby_prof/rp_measure_allocations.c +25 -51
  17. data/ext/ruby_prof/rp_measure_memory.c +21 -56
  18. data/ext/ruby_prof/rp_measure_process_time.c +37 -43
  19. data/ext/ruby_prof/rp_measure_wall_time.c +40 -21
  20. data/ext/ruby_prof/rp_measurement.c +221 -0
  21. data/ext/ruby_prof/rp_measurement.h +50 -0
  22. data/ext/ruby_prof/rp_method.c +279 -439
  23. data/ext/ruby_prof/rp_method.h +33 -45
  24. data/ext/ruby_prof/rp_profile.c +902 -0
  25. data/ext/ruby_prof/rp_profile.h +36 -0
  26. data/ext/ruby_prof/rp_stack.c +163 -132
  27. data/ext/ruby_prof/rp_stack.h +18 -28
  28. data/ext/ruby_prof/rp_thread.c +192 -124
  29. data/ext/ruby_prof/rp_thread.h +18 -8
  30. data/ext/ruby_prof/ruby_prof.c +36 -778
  31. data/ext/ruby_prof/ruby_prof.h +11 -45
  32. data/ext/ruby_prof/vc/ruby_prof.vcxproj +18 -12
  33. data/lib/ruby-prof.rb +4 -21
  34. data/lib/ruby-prof/assets/call_stack_printer.html.erb +710 -0
  35. data/lib/ruby-prof/assets/call_stack_printer.png +0 -0
  36. data/lib/ruby-prof/assets/graph_printer.html.erb +355 -0
  37. data/lib/ruby-prof/call_tree.rb +57 -0
  38. data/lib/ruby-prof/call_tree_visitor.rb +36 -0
  39. data/lib/ruby-prof/compatibility.rb +37 -107
  40. data/lib/ruby-prof/exclude_common_methods.rb +198 -0
  41. data/lib/ruby-prof/measurement.rb +17 -0
  42. data/lib/ruby-prof/method_info.rb +47 -90
  43. data/lib/ruby-prof/printers/abstract_printer.rb +73 -50
  44. data/lib/ruby-prof/printers/call_info_printer.rb +24 -12
  45. data/lib/ruby-prof/printers/call_stack_printer.rb +66 -152
  46. data/lib/ruby-prof/printers/call_tree_printer.rb +20 -12
  47. data/lib/ruby-prof/printers/dot_printer.rb +5 -5
  48. data/lib/ruby-prof/printers/flat_printer.rb +6 -24
  49. data/lib/ruby-prof/printers/graph_html_printer.rb +6 -192
  50. data/lib/ruby-prof/printers/graph_printer.rb +11 -14
  51. data/lib/ruby-prof/printers/multi_printer.rb +66 -23
  52. data/lib/ruby-prof/profile.rb +10 -3
  53. data/lib/ruby-prof/thread.rb +5 -20
  54. data/lib/ruby-prof/version.rb +1 -1
  55. data/ruby-prof.gemspec +9 -2
  56. data/test/abstract_printer_test.rb +0 -27
  57. data/test/alias_test.rb +126 -0
  58. data/test/basic_test.rb +1 -86
  59. data/test/call_tree_visitor_test.rb +32 -0
  60. data/test/call_trees_test.rb +66 -0
  61. data/test/dynamic_method_test.rb +0 -2
  62. data/test/exclude_methods_test.rb +17 -12
  63. data/test/fiber_test.rb +214 -23
  64. data/test/gc_test.rb +105 -0
  65. data/test/inverse_call_tree_test.rb +175 -0
  66. data/test/line_number_test.rb +118 -40
  67. data/test/marshal_test.rb +115 -0
  68. data/test/measure_allocations.rb +30 -0
  69. data/test/measure_allocations_test.rb +361 -12
  70. data/test/measure_allocations_trace_test.rb +375 -0
  71. data/test/measure_memory_trace_test.rb +1101 -0
  72. data/test/measure_process_time_test.rb +757 -33
  73. data/test/measure_times.rb +56 -0
  74. data/test/measure_wall_time_test.rb +329 -149
  75. data/test/multi_printer_test.rb +1 -34
  76. data/test/pause_resume_test.rb +24 -15
  77. data/test/prime.rb +1 -1
  78. data/test/prime_script.rb +6 -0
  79. data/test/printer_call_stack_test.rb +28 -0
  80. data/test/printer_call_tree_test.rb +31 -0
  81. data/test/printer_flat_test.rb +68 -0
  82. data/test/printer_graph_html_test.rb +60 -0
  83. data/test/printer_graph_test.rb +41 -0
  84. data/test/printers_test.rb +32 -166
  85. data/test/printing_recursive_graph_test.rb +26 -72
  86. data/test/recursive_test.rb +68 -77
  87. data/test/stack_printer_test.rb +2 -15
  88. data/test/start_stop_test.rb +22 -25
  89. data/test/test_helper.rb +6 -261
  90. data/test/thread_test.rb +11 -54
  91. data/test/unique_call_path_test.rb +25 -107
  92. data/test/yarv_test.rb +1 -0
  93. metadata +43 -41
  94. data/examples/flat.txt +0 -50
  95. data/examples/graph.dot +0 -84
  96. data/examples/graph.html +0 -823
  97. data/examples/graph.txt +0 -139
  98. data/examples/multi.flat.txt +0 -23
  99. data/examples/multi.graph.html +0 -760
  100. data/examples/multi.grind.dat +0 -114
  101. data/examples/multi.stack.html +0 -547
  102. data/examples/stack.html +0 -547
  103. data/ext/ruby_prof/rp_call_info.c +0 -425
  104. data/ext/ruby_prof/rp_call_info.h +0 -53
  105. data/ext/ruby_prof/rp_measure.c +0 -40
  106. data/ext/ruby_prof/rp_measure.h +0 -45
  107. data/ext/ruby_prof/rp_measure_cpu_time.c +0 -136
  108. data/ext/ruby_prof/rp_measure_gc_runs.c +0 -73
  109. data/ext/ruby_prof/rp_measure_gc_time.c +0 -60
  110. data/lib/ruby-prof/aggregate_call_info.rb +0 -76
  111. data/lib/ruby-prof/assets/call_stack_printer.css.html +0 -117
  112. data/lib/ruby-prof/assets/call_stack_printer.js.html +0 -385
  113. data/lib/ruby-prof/call_info.rb +0 -115
  114. data/lib/ruby-prof/call_info_visitor.rb +0 -40
  115. data/lib/ruby-prof/printers/flat_printer_with_line_numbers.rb +0 -83
  116. data/lib/ruby-prof/profile/exclude_common_methods.rb +0 -207
  117. data/lib/ruby-prof/profile/legacy_method_elimination.rb +0 -50
  118. data/test/aggregate_test.rb +0 -136
  119. data/test/block_test.rb +0 -74
  120. data/test/call_info_test.rb +0 -78
  121. data/test/call_info_visitor_test.rb +0 -31
  122. data/test/issue137_test.rb +0 -63
  123. data/test/measure_cpu_time_test.rb +0 -212
  124. data/test/measure_gc_runs_test.rb +0 -32
  125. data/test/measure_gc_time_test.rb +0 -36
  126. data/test/measure_memory_test.rb +0 -33
  127. data/test/method_elimination_test.rb +0 -84
  128. data/test/module_test.rb +0 -45
  129. data/test/stack_test.rb +0 -138
@@ -1,267 +1,12 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require "rubygems"
4
- gem "minitest"
5
-
6
- # To make testing/debugging easier, test within this source tree versus an installed gem
7
- dir = File.dirname(__FILE__)
8
- root = File.expand_path(File.join(dir, '..'))
9
- lib = File.expand_path(File.join(root, 'lib'))
10
- ext = File.expand_path(File.join(root, 'ext', 'ruby_prof'))
11
-
12
- $LOAD_PATH << lib
13
- $LOAD_PATH << ext
14
-
15
- require 'ruby-prof'
16
-
17
- # stub deprecation warnings
18
- module RubyProf
19
- module SuppressDeprecationWarnings
20
- def deprecation_warning(*args)
21
- super if ENV['SHOW_RUBY_PROF_DEPRECATION_WARNINGS'] == '1'
22
- end
23
- end
24
- extend SuppressDeprecationWarnings
25
- end
3
+ # Disable minitest parallel tests. The problem is the thread switching will cahnge test results
4
+ # (self vs wait time)
5
+ ENV["N"] = "0"
26
6
 
7
+ require 'bundler/setup'
27
8
  require 'minitest/autorun'
9
+ require 'ruby-prof'
28
10
 
29
11
  class TestCase < Minitest::Test
30
- # I know this sucks, but ...
31
- def assert_nothing_raised(*)
32
- yield
33
- end
34
-
35
- def before_setup
36
- # make sure to exclude all threads except the one running the test
37
- # minitest allocates a thread pool and they would otherwise show
38
- # up in the profile data, breaking tests randomly
39
- RubyProf.exclude_threads = Thread.list.select{|t| t != Thread.current}
40
- end
41
-
42
- def after_teardown
43
- # reset exclude threads after testing
44
- RubyProf.exclude_threads = nil
45
- end
46
- end
47
-
48
- require File.expand_path('../prime', __FILE__)
49
-
50
- # Some classes used in measurement tests
51
- module RubyProf
52
- class C1
53
- def C1.hello
54
- sleep(0.1)
55
- end
56
-
57
- def hello
58
- sleep(0.2)
59
- end
60
- end
61
-
62
- module M1
63
- def hello
64
- sleep(0.3)
65
- end
66
- end
67
-
68
- class C2
69
- include M1
70
- extend M1
71
- end
72
-
73
- class C3
74
- def hello
75
- sleep(0.4)
76
- end
77
- end
78
-
79
- module M4
80
- def hello
81
- sleep(0.5)
82
- end
83
- end
84
-
85
- module M5
86
- include M4
87
- def goodbye
88
- hello
89
- end
90
- end
91
-
92
- class C6
93
- include M5
94
- def test
95
- goodbye
96
- end
97
- end
98
-
99
- class C7
100
- def self.busy_wait
101
- t = Time.now.to_f
102
- while Time.now.to_f - t < 0.1; end
103
- end
104
-
105
- def self.sleep_wait
106
- sleep 0.1
107
- end
108
-
109
- def busy_wait
110
- t = Time.now.to_f
111
- while Time.now.to_f - t < 0.2; end
112
- end
113
-
114
- def sleep_wait
115
- sleep 0.2
116
- end
117
- end
118
-
119
- module M7
120
- def busy_wait
121
- t = Time.now.to_f
122
- while Time.now.to_f - t < 0.3; end
123
- end
124
-
125
- def sleep_wait
126
- sleep 0.3
127
- end
128
- end
129
-
130
- class C8
131
- include M7
132
- extend M7
133
- end
134
-
135
- def self.ruby_major_version
136
- match = RUBY_VERSION.match(/(\d)\.(\d)/)
137
- return Integer(match[1])
138
- end
139
-
140
- def self.ruby_minor_version
141
- match = RUBY_VERSION.match(/(\d)\.(\d)/)
142
- return Integer(match[2])
143
- end
144
-
145
- def self.parent_object
146
- if ruby_major_version == 1 && ruby_minor_version == 8
147
- Object
148
- else
149
- BasicObject
150
- end
151
- end
152
-
153
- def self.ruby_2?
154
- ruby_major_version == 2
155
- end
156
-
157
- # store printer output in this directory
158
- def self.tmpdir
159
- path = File.expand_path('../../tmp', __FILE__)
160
- unless Dir.exist?(path)
161
- Dir.mkdir(path)
162
- end
163
- path
164
- end
165
- end
166
-
167
- module MemoryTestHelper
168
- def memory_test_helper
169
- result = RubyProf.profile {Array.new}
170
- total = result.threads.first.methods.inject(0) { |sum, m| sum + m.total_time }
171
- assert(total < 1_000_000, 'Total should not have subtract overflow error')
172
- total
173
- end
174
- end
175
-
176
- module PrinterTestHelper
177
- Metrics = Struct.new(:name, :total, :self_t, :wait, :child, :calls)
178
- class Metrics
179
- def pp
180
- "%s[total: %.2f, self: %.2f, wait: %.2f, child: %.2f, calls: %s]" %
181
- [name, total, self_t, wait, child, calls]
182
- end
183
- end
184
-
185
- Entry = Struct.new(:total_p, :self_p, :metrics, :parents, :children)
186
- class Entry
187
- def child(name)
188
- children.detect{|m| m.name == name}
189
- end
190
-
191
- def parent(name)
192
- parents.detect{|m| m.name == name}
193
- end
194
-
195
- def pp
196
- res = ""
197
- res << "NODE (total%%: %.2f, self%%: %.2f) %s\n" % [total_p, self_p, metrics.pp]
198
- res << " PARENTS:\n"
199
- parents.each {|m| res << " " + m.pp << "\n"}
200
- res << " CHILDREN:\n"
201
- children.each {|m| res << " " + m.pp << "\n"}
202
- res
203
- end
204
- end
205
-
206
- class MetricsArray < Array
207
- def metrics_for(name)
208
- detect {|e| e.metrics.name == name}
209
- end
210
-
211
- def pp(io = STDOUT)
212
- entries = map do |e|
213
- begin
214
- e.pp
215
- rescue
216
- puts $!.message + e.inspect
217
- ""
218
- end
219
- end
220
- io.puts entries.join("--------------------------------------------------\n")
221
- end
222
-
223
- def self.parse(str)
224
- res = new
225
- entry = nil
226
- relatives = []
227
- state = :preamble
228
-
229
- str.each_line do |l|
230
- line = l.chomp.strip
231
- if line =~ /-----/
232
- if state == :preamble
233
- state = :parsing_parents
234
- entry = Entry.new
235
- elsif state == :parsing_parents
236
- entry = Entry.new
237
- elsif state == :parsing_children
238
- entry.children = relatives
239
- res << entry
240
- entry = Entry.new
241
- relatives = []
242
- state = :parsing_parents
243
- end
244
- elsif line =~ /^\s*$/ || line =~ /indicates recursively called methods/
245
- next
246
- elsif state != :preamble
247
- elements = line.split(/\s+/)
248
- method = elements.pop
249
- numbers = elements[0..-2].map(&:to_f)
250
- metrics = Metrics.new(method, *numbers[-4..-1], elements[-1])
251
- if numbers.size == 6
252
- entry.metrics = metrics
253
- entry.total_p = numbers[0]
254
- entry.self_p = numbers[1]
255
- entry.parents = relatives
256
- entry.children = relatives = []
257
- state = :parsing_children
258
- res << entry
259
- else
260
- relatives << metrics
261
- end
262
- end
263
- end
264
- res
265
- end
266
- end
267
- end
12
+ end
@@ -75,10 +75,7 @@ class ThreadTest < TestCase
75
75
  assert_in_delta(0, method.self_time, 0.05)
76
76
  assert_in_delta(0, method.wait_time, 0.05)
77
77
  assert_in_delta(1, method.children_time, 0.05)
78
- assert_equal(1, method.call_infos.length)
79
- call_info = method.call_infos[0]
80
- assert_equal('ThreadTest#test_thread_timings', call_info.call_sequence)
81
- assert_equal(1, call_info.children.length)
78
+ assert_equal(0, method.call_trees.callers.length)
82
79
 
83
80
  method = methods[1]
84
81
  assert_equal('Kernel#sleep', method.full_name)
@@ -88,10 +85,8 @@ class ThreadTest < TestCase
88
85
  assert_in_delta(0, method.wait_time, 0.05)
89
86
  assert_in_delta(0, method.children_time, 0.05)
90
87
 
91
- assert_equal(1, method.call_infos.length)
92
- call_info = method.call_infos[0]
93
- assert_equal('ThreadTest#test_thread_timings->Kernel#sleep', call_info.call_sequence)
94
- assert_equal(0, call_info.children.length)
88
+ assert_equal(1, method.call_trees.callers.length)
89
+ assert_equal(0, method.call_trees.callees.length)
95
90
 
96
91
  # Check foreground thread
97
92
  rp_thread = result.threads.detect {|athread| athread.id == Thread.current.object_id}
@@ -110,10 +105,8 @@ class ThreadTest < TestCase
110
105
  assert_in_delta(0, method.wait_time, 0.05)
111
106
  assert_in_delta(1, method.children_time, 0.05)
112
107
 
113
- assert_equal(1, method.call_infos.length)
114
- call_info = method.call_infos[0]
115
- assert_equal('ThreadTest#test_thread_timings', call_info.call_sequence)
116
- assert_equal(2, call_info.children.length)
108
+ assert_equal(0, method.call_trees.callers.length)
109
+ assert_equal(2, method.call_trees.callees.length)
117
110
 
118
111
  method = methods[1]
119
112
  assert_equal('Thread#join', method.full_name)
@@ -123,10 +116,8 @@ class ThreadTest < TestCase
123
116
  assert_in_delta(1.0, method.wait_time, 0.05)
124
117
  assert_in_delta(0, method.children_time, 0.05)
125
118
 
126
- assert_equal(1, method.call_infos.length)
127
- call_info = method.call_infos[0]
128
- assert_equal('ThreadTest#test_thread_timings->Thread#join', call_info.call_sequence)
129
- assert_equal(0, call_info.children.length)
119
+ assert_equal(1, method.call_trees.callers.length)
120
+ assert_equal(0, method.call_trees.callees.length)
130
121
 
131
122
  method = methods[2]
132
123
  assert_equal('<Class::Thread>#new', method.full_name)
@@ -136,10 +127,8 @@ class ThreadTest < TestCase
136
127
  assert_in_delta(0, method.wait_time, 0.05)
137
128
  assert_in_delta(0, method.children_time, 0.05)
138
129
 
139
- assert_equal(1, method.call_infos.length)
140
- call_info = method.call_infos[0]
141
- assert_equal('ThreadTest#test_thread_timings-><Class::Thread>#new', call_info.call_sequence)
142
- assert_equal(1, call_info.children.length)
130
+ assert_equal(1, method.call_trees.callers.length)
131
+ assert_equal(1, method.call_trees.callees.length)
143
132
 
144
133
  method = methods[3]
145
134
  assert_equal('Thread#initialize', method.full_name)
@@ -149,39 +138,7 @@ class ThreadTest < TestCase
149
138
  assert_in_delta(0, method.wait_time, 0.05)
150
139
  assert_in_delta(0, method.children_time, 0.05)
151
140
 
152
- assert_equal(1, method.call_infos.length)
153
- call_info = method.call_infos[0]
154
- assert_equal('ThreadTest#test_thread_timings-><Class::Thread>#new->Thread#initialize', call_info.call_sequence)
155
- assert_equal(0, call_info.children.length)
156
- end
157
-
158
- # useless test: what does it test?
159
- def test_thread_back_and_forth
160
- result = nil
161
- seconds = Benchmark.realtime do
162
- result = RubyProf.profile do
163
- a = Thread.new { 100_000.times { sleep 0 }}
164
- b = Thread.new { 100_000.times { sleep 0 }}
165
- a.join
166
- b.join
167
- end
168
- end
169
- methods = result.threads.map {|thread| thread.methods}
170
- timings = methods.flatten.sort
171
- assert(timings[-1].total_time < seconds)
172
- end
173
-
174
- # useless test: what does it test?
175
- def test_thread
176
- RubyProf.profile do
177
- begin
178
- Timeout::timeout(2) do
179
- while true
180
- next
181
- end
182
- end
183
- rescue Timeout::Error
184
- end
185
- end
141
+ assert_equal(1, method.call_trees.callers.length)
142
+ assert_equal(0, method.call_trees.callees.length)
186
143
  end
187
144
  end
@@ -27,24 +27,15 @@ end
27
27
 
28
28
  # -- Tests ----
29
29
  class UniqueCallPathTest < TestCase
30
- def test_root_method
30
+ def test_root
31
31
  unique_call_path = UniqueCallPath.new
32
32
 
33
33
  result = RubyProf.profile do
34
34
  unique_call_path.method_a(1)
35
35
  end
36
36
 
37
- root_methods = Array.new
38
- result.threads.each do |thread|
39
- thread.methods.each do | m |
40
- if m.root?
41
- root_methods.push(m)
42
- end
43
- end
44
- end
45
-
46
- assert_equal(1, root_methods.length)
47
- assert_equal("UniqueCallPathTest#test_root_method", root_methods[0].full_name)
37
+ root_call_info = result.threads.first.call_tree
38
+ assert_equal("UniqueCallPathTest#test_root", root_call_info.target.full_name)
48
39
  end
49
40
 
50
41
  def test_root_children
@@ -55,25 +46,8 @@ class UniqueCallPathTest < TestCase
55
46
  unique_call_path.method_k(2)
56
47
  end
57
48
 
58
- root_methods = Array.new
59
- result.threads.each do |thread|
60
- thread.methods.each do | m |
61
- if m.root?
62
- root_methods.push(m)
63
- end
64
- end
65
- end
66
-
67
- assert_equal(1, root_methods.length)
68
-
69
- root_children = Array.new
70
- root_methods[0].children.each do | c |
71
- if c.parent.target.eql?(root_methods[0])
72
- root_children.push(c)
73
- end
74
- end
75
-
76
- children = root_children.sort do |c1, c2|
49
+ root_call_info = result.threads.first.call_tree
50
+ children = root_call_info.children.sort do |c1, c2|
77
51
  c1.target.full_name <=> c2.target.full_name
78
52
  end
79
53
 
@@ -90,67 +64,23 @@ class UniqueCallPathTest < TestCase
90
64
  unique_call_path.method_k(2)
91
65
  end
92
66
 
93
- root_methods = Array.new
94
- result.threads.each do |thread|
95
- thread.methods.each do | m |
96
- if m.root?
97
- root_methods.push(m)
98
- end
99
- end
100
- end
101
-
102
- assert_equal(1, root_methods.length)
103
- method = root_methods[0]
104
- assert_equal('UniqueCallPathTest#test_children_of', method.full_name)
67
+ root_call_info = result.threads.first.call_tree
68
+ assert_equal("UniqueCallPathTest#test_children_of", root_call_info.target.full_name)
105
69
 
106
- call_info_a = nil
107
- root_methods[0].children.each do | c |
108
- if c.target.full_name == "UniqueCallPath#method_a"
109
- call_info_a = c
110
- break
111
- end
70
+ call_info_a = root_call_info.children.detect do |call_tree|
71
+ call_tree.target.full_name == "UniqueCallPath#method_a"
112
72
  end
73
+ refute_nil(call_info_a)
113
74
 
114
- assert !call_info_a.nil?
115
-
116
- children_of_a = Array.new
117
-
118
- call_info_a.children.each do | c |
75
+ children_of_a = call_info_a.children.inject(Array.new) do |array, c|
119
76
  if c.parent.eql?(call_info_a)
120
- children_of_a.push(c)
77
+ array << c
121
78
  end
79
+ array
122
80
  end
123
81
 
124
- assert_equal(2, call_info_a.target.children.length)
125
-
126
- children_of_a = children_of_a.sort do |c1, c2|
127
- c1.target.full_name <=> c2.target.full_name
128
- end
129
-
130
- assert_equal(1, children_of_a.length)
131
- assert_equal("UniqueCallPath#method_b", children_of_a[0].target.full_name)
132
- end
133
-
134
- def test_id2ref
135
- unique_call_path = UniqueCallPath.new
136
-
137
- result = RubyProf.profile do
138
- unique_call_path.method_a(1)
139
- end
140
-
141
- root_methods = Array.new
142
- result.threads.each do |thread|
143
- thread.methods.each do | m |
144
- if m.root?
145
- root_methods.push(m)
146
- end
147
- end
148
- end
149
-
150
- child = root_methods[0].children[0]
151
-
152
- refute_equal(0, child.object_id)
153
- #assert_equal(RubyProf::CallInfo.id2ref(child.id).target.full_name, child.target.full_name)
82
+ assert_equal(1, call_info_a.children.length)
83
+ assert_equal("UniqueCallPath#method_b", call_info_a.children.first.target.full_name)
154
84
  end
155
85
 
156
86
  def test_unique_path
@@ -161,35 +91,23 @@ class UniqueCallPathTest < TestCase
161
91
  unique_call_path.method_k(1)
162
92
  end
163
93
 
164
- root_methods = Array.new
165
- result.threads.each do |thread|
166
- thread.methods.each do | m |
167
- if m.root?
168
- root_methods.push(m)
169
- end
170
- end
171
- end
172
-
173
- assert_equal(1, root_methods.length)
94
+ root_call_info = result.threads.first.call_tree
95
+ assert_equal("UniqueCallPathTest#test_unique_path", root_call_info.target.full_name)
174
96
 
175
- call_info_a = nil
176
- root_methods[0].children.each do | c |
177
- if c.target.full_name == "UniqueCallPath#method_a"
178
- call_info_a = c
179
- break
180
- end
97
+ call_info_a = root_call_info.children.detect do |call_tree|
98
+ call_tree.target.full_name == "UniqueCallPath#method_a"
181
99
  end
100
+ refute_nil(call_info_a)
182
101
 
183
- assert !call_info_a.nil?
184
-
185
- children_of_a = Array.new
186
- call_info_a.children.each do |c|
102
+ children_of_a = call_info_a.children.reduce(Array.new) do |array, c|
187
103
  if c.parent.eql?(call_info_a)
188
- children_of_a.push(c)
104
+ array << c
189
105
  end
106
+ array
190
107
  end
191
108
 
192
- assert_equal(2, call_info_a.target.children.length)
109
+ assert_equal(1, call_info_a.children.length)
110
+ assert_equal(1, children_of_a.length)
193
111
 
194
112
  children_of_a = children_of_a.sort do |c1, c2|
195
113
  c1.target.full_name <=> c2.target.full_name