1require 'mspec/expectations/expectations'
2require 'mspec/runner/formatters/dotted'
3
4class ProfileFormatter < DottedFormatter
5  def initialize(out=nil)
6    super
7
8    @describe_name = nil
9    @describe_time = nil
10    @describes = []
11    @its = []
12  end
13
14  def register
15    super
16    MSpec.register :enter, self
17  end
18
19  # Callback for the MSpec :enter event. Prints the
20  # +describe+ block string.
21  def enter(describe)
22    if @describe_time
23      @describes << [@describe_name, Time.now.to_f - @describe_time]
24    end
25
26    @describe_name = describe
27    @describe_time = Time.now.to_f
28  end
29
30  # Callback for the MSpec :before event. Prints the
31  # +it+ block string.
32  def before(state)
33    super
34
35    @it_name = state.it
36    @it_time = Time.now.to_f
37  end
38
39  # Callback for the MSpec :after event. Prints a
40  # newline to finish the description string output.
41  def after(state)
42    @its << [@describe_name, @it_name, Time.now.to_f - @it_time]
43    super
44  end
45
46  def finish
47    puts "\nProfiling info:"
48
49    desc = @describes.sort { |a,b| b.last <=> a.last }
50    desc.delete_if { |a| a.last <= 0.001 }
51    show = desc[0, 100]
52
53    puts "Top #{show.size} describes:"
54
55    show.each do |des, time|
56      printf "%3.3f - %s\n", time, des
57    end
58
59    its = @its.sort { |a,b| b.last <=> a.last }
60    its.delete_if { |a| a.last <= 0.001 }
61    show = its[0, 100]
62
63    puts "\nTop #{show.size} its:"
64    show.each do |des, it, time|
65      printf "%3.3f - %s %s\n", time, des, it
66    end
67
68    super
69  end
70end
71