Class: SimpleCov::Formatter::SimpleHTMLFormatter

Inherits:
Object
  • Object
show all
Includes:
REXML
Defined in:
lib/simplecov-simple-html.rb,
lib/simplecov-simple-html/version.rb

Overview

A simple HTML formater for SimpleCov There a coverage file created for each ruby file tested

Constant Summary collapse

VERSION =

the version number of SimpleCov::Formatter::SimpleHTMLFormatter

"0.2.0"

Instance Method Summary collapse

Instance Method Details

#fixup_path(source_doc) ⇒ void

This method returns an undefined value.

fixup the path

Parameters:

  • source_doc (REXML::Document)


20
21
22
23
24
25
26
27
28
# File 'lib/simplecov-simple-html.rb', line 20

def fixup_path(source_doc)
  source_doc.each_element('//link') do |e|
    e.add_attribute('href', e.attribute('href').to_s.sub('VERSION', SimpleCov::Formatter::SimpleHTMLFormatter::VERSION))
  end
  source_doc.each_element('//script') do |e|
    e.add_attribute('src', e.attribute('src').to_s.sub('VERSION', SimpleCov::Formatter::SimpleHTMLFormatter::VERSION))
  end
  nil
end

#format(result) ⇒ void

Note:

Creates a directory and serveral files

This method returns an undefined value.

Format the coverage results

Parameters:

  • result (SimpleCov::Result)

    The SimpleCov::Result



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
# File 'lib/simplecov-simple-html.rb', line 33

def format(result)
  Dir[File.join(File.dirname(__FILE__), '../public/*')].each do |path|
    FileUtils.cp_r(path, asset_output_path)
  end
  File.open(File.join(File.dirname(__FILE__), '../views/source.html.in'), "r") do |ifile|
    source_doc = REXML::Document.new ifile
    fixup_path(source_doc)
    result.source_files.each do |source_file|
      doc = source_doc.deep_clone
      doc.each_recursive do |e|
        case e.attribute('class').to_s
        when 'filename'
          e.text = shortened_filename source_file.filename
        when 'covered_percent'
          e.text = source_file.covered_percent.round(2).to_s
          e.parent.attributes['style'] = "color: #{ coverage_css_class(source_file.covered_percent) };"
        when 'lines_of_code'
          e.text = source_file.lines_of_code
        when 'covered_lines'
          e.text = source_file.covered_lines.size
        when 'missed_lines'
          e.text = source_file.missed_lines.size
        end
      end
      ol = doc.get_elements('//div/pre/ol')[0]
      li = doc.get_elements('//div/pre/ol/li')[0]
      ol.delete_element(li)
      source_file.lines.each_with_index do |line|
        nli = li.deep_clone
        nli.add_attribute("class", line.status)
        nli.add_attribute("data-linenumber", line.number)
        nli.add_attribute("data-hits", line.coverage ? line.coverage : '')

        nli.get_elements('code')[0].text = line.src
        if line.covered?
          nli.get_elements('span')[0].text = line.coverage
        elsif line.skipped?
          nli.get_elements('span')[0].text = line.coverage
        else
          nli.delete_element(nli.get_elements('span')[0])
        end
        ol << nli
      end
      filename = File.join(output_path, shortened_filename(source_file.filename).gsub('/', '_') + '.html')
      FileUtils.mkdir_p(File.dirname(filename))
      File.open(filename, 'w') do |ofile|
        ofile.puts doc.to_s
      end
    end
  end
  groups = [ "All Files" ] +  result.groups.each_key.to_a
  a = Array.new
  a = a.push [ "All Files", result.source_files ]
  a += result.groups.to_a
  groups_hash = Hash[ a ]

  File.open(File.join(File.dirname(__FILE__), '../views/index.html.in'), "r") do |ifile|
    data = ifile.read
    groups.each_with_index do |name, i|
      doc = REXML::Document.new data
      source_files = groups_hash[name]
      fixup_path(doc)
      doc.xpath
      body = doc.root.elements['body/div']
      XPath.each(body, '//*[@class="source_files_covered_percent"]') do |element|  
        element.text = source_files.covered_percent.round(2)
        element.parent.attributes['class'] = coverage_css_class(source_files.covered_percent)
      end
      XPath.each(body, '//*/span[@class="covered_strength_value"]') do |x|  
        x.text = source_files.covered_strength.round(2)
        x.parent.attributes['class'] =  strength_css_class(source_files.covered_strength)
      end
      XPath.each(body, '//*/span[@class="files_total"]') do |x|  
 x.text = source_files.size
  end
      XPath.each(body, '//*/span[@class="file_lines"]') do |x|  
 x.text = source_files.lines_of_code
  end
      XPath.each(body, '//*/span[@class="covered_lines"]') do |x|  
 x.text = source_files.covered_lines
  end
      XPath.each(body, '//*/span[@class="missed_lines"]') do |x|  
 x.text = source_files.missed_lines
  end
      XPath.each(body, '//*/ul[@class="group_tabs"]').each do |x|  
#p x.to_s
  end
      body.each_element do |body_element|
        if body_element.attribute('class')
          case body_element.attribute('class').to_s
          when 'timestamp'
            body_element.each_element do |e2|
              case e2.name.to_s
              when 'abbr'
                time = Time.now
                e2.add_attribute('title', time.iso8601)
                e2.text = time.iso8601
              end
            end
          when 'group_tabs'
     fli = nil
            body_element.to_a.each do |li|
              case li
when REXML::Element
         fli = li.dup unless fli
                body_element.delete_element li
when REXML::Text
                body_element.delete li
else
                raise 'unknown'
end
            end
     groups.each_with_index do |g, gi|
g_source_files = groups_hash[g]
nli = fli.deep_clone
if g == name
  nli.attributes['class'] = 'active'
end
nli.each_element('a/span[@class="tab_group_name"]') do |x|
  x.text = g
end
nli.each_element('a/span[@class="color"]') do |x|
  x.attributes['class'] = coverage_css_class(g_source_files.covered_percent)
end
nli.each_element('a/span/span[@class="tab_coverage"]') do |x|
  x.text = g_source_files.covered_percent.round(2)
end
nli.each_element('a') do |x|
  if gi > 0
    x.attributes['href'] = 'index%d.html' % gi
  else
    x.attributes['href'] = 'index.html'
  end
end
body_element.add_element nli
     end
          end
        end
        if body_element.attribute('id')
          case body_element.attribute('id').to_s
          when 'content'
            file_list_container = body_element.get_elements("//div[@class='file_list_container']")[0]
            file_list_container.add_attribute('id', 'AllFiles')
#           x = file_list_container.deep_clone
            x = file_list_container
            x.each_element do |e1|
              case e1.name
              when 'h2'
                e1.each_recursive do |e2|
                  case e2.attribute('class').to_s
                  when 'group_name'
                    e2.text = name
                  end
                end
              when 'table'
                tbody = e1.get_elements('//tbody')[0]
                body_element.each_element('//tbody/tr') do |tr|
                  tbody.delete_element tr
                  source_files.each do |source_file|
                    ntr = tr.deep_clone
                    x = ntr.get_elements('//td')
                    filename = x[0].get_elements('a')[0]
                    filename.text = shortened_filename source_file.filename
                    filename.add_attribute('href', shortened_filename(source_file.filename).gsub('/', '_') + '.html')
                    x[1].add_attribute('class', coverage_css_class(source_file.covered_percent))
                    x[1].text = source_file.covered_percent.round(2)
                    x[2].text = source_file.lines.count
                    x[3].text = source_file.covered_lines.size + source_file.missed_lines.count
                    x[4].text = source_file.covered_lines.size
                    x[5].text = source_file.missed_lines.size
                    x[6].text = source_file.covered_strength
                    tbody << ntr
                  end
                end
              else
#puts e
              end
            end
          when 'footer'
            body_element.each_element do |e|
              case body_element.attribute('id').to_s
              when 'simplecov_version'
                body_element.text = SimpleCov::VERSION
              when 'result.command_name'
                body_element.text = result.command_name
              else 
#puts body_element
              end
            end
          else
puts "Id #{ body_element.attribute('id').to_s }"
          end
        end
      end
      if i == 0
        ofilename = 'index.html'
      else
        ofilename = "index#{i}.html"
      end
      File.open(File.join(output_path, ofilename), "w+") do |ofile|
        ofile.puts doc.to_s
      end
    end
  end
  puts output_message(result)
  nil
end

#output_message(result) ⇒ String

Generate the coverage report text

Parameters:

  • result (SimpleCov::Result)

    The SimpleCov::Result

Returns:

  • (String)

    the coverage report



244
245
246
# File 'lib/simplecov-simple-html.rb', line 244

def output_message(result)
  "Coverage report generated for #{result.command_name} to #{output_path}. #{result.covered_lines} / #{result.total_lines} LOC (#{result.covered_percent.round(2)}%) covered."
end