class RSpec::Core::Formatters::HtmlFormatter
def current_indentation
def current_indentation "style=\"margin-left: #{(example_group.ancestors.size - 1) * 15}px;\"" end
def dump_failures
def dump_failures end
def dump_pending
def dump_pending end
def dump_summary(duration, example_count, failure_count, pending_count)
def dump_summary(duration, example_count, failure_count, pending_count) # TODO - kill dry_run? if dry_run? totals = "This was a dry-run" else totals = "#{example_count} example#{'s' unless example_count == 1}, #{failure_count} failure#{'s' unless failure_count == 1}" totals << ", #{pending_count} pending" if pending_count > 0 end @output.puts "<script type=\"text/javascript\">document.getElementById('duration').innerHTML = \"Finished in <strong>#{duration} seconds</strong>\";</script>" @output.puts "<script type=\"text/javascript\">document.getElementById('totals').innerHTML = \"#{totals}\";</script>" @output.puts "</div>" @output.puts "</div>" @output.puts "</body>" @output.puts "</html>" @output.flush end
def example_failed(example)
def example_failed(example) counter = 0 exception = example.metadata[:execution_result][:exception] extra = extra_failure_content(exception) failure_style = 'failed' failure_style = RSpec::Core::PendingExampleFixedError === exception ? 'pending_fixed' : 'failed' @output.puts " <script type=\"text/javascript\">makeRed('rspec-header');</script>" unless @header_red @header_red = true @output.puts " <script type=\"text/javascript\">makeRed('example_group_#{example_group_number}');</script>" unless @example_group_red @example_group_red = true move_progress @output.puts " <dd class=\"spec #{failure_style}\">" @output.puts " <span class=\"failed_spec_name\">#{h(example.description)}</span>" @output.puts " <div class=\"failure\" id=\"failure_#{counter}\">" @output.puts " <div class=\"message\"><pre>#{h(exception.message)}</pre></div>" unless exception.nil? @output.puts " <div class=\"backtrace\"><pre>#{format_backtrace(exception.backtrace, example).join("\n")}</pre></div>" if exception @output.puts extra unless extra == "" @output.puts " </div>" @output.puts " </dd>" @output.flush end
def example_group_number
def example_group_number @example_group_number end
def example_group_started(example_group)
def example_group_started(example_group) super(example_group) @example_group_red = false @example_group_number += 1 unless example_group_number == 1 @output.puts " </dl>" @output.puts "</div>" end @output.puts "<div class=\"example_group\">" @output.puts " <dl #{current_indentation}>" @output.puts " <dt id=\"example_group_#{example_group_number}\">#{h(example_group.description)}</dt>" @output.flush end
def example_number
def example_number @example_number end
def example_passed(example)
def example_passed(example) move_progress @output.puts " <dd class=\"spec passed\"><span class=\"passed_spec_name\">#{h(example.description)}</span></dd>" @output.flush end
def example_pending(example)
def example_pending(example) message = example.metadata[:execution_result][:pending_message] @output.puts " <script type=\"text/javascript\">makeYellow('rspec-header');</script>" unless @header_red @output.puts " <script type=\"text/javascript\">makeYellow('example_group_#{example_group_number}');</script>" unless @example_group_red move_progress @output.puts " <dd class=\"spec not_implemented\"><span class=\"not_implemented_spec_name\">#{h(example.description)} (PENDING: #{h(message)})</span></dd>" @output.flush end
def example_started(example)
def example_started(example) super(example) @example_number += 1 end
def extra_failure_content(exception)
could output links to images or other files produced during the specs.
Override this method if you wish to output extra HTML for a failed spec. For example, you
def extra_failure_content(exception) require 'rspec/core/formatters/snippet_extractor' @snippet_extractor ||= SnippetExtractor.new " <pre class=\"ruby\"><code>#{@snippet_extractor.snippet(exception)}</code></pre>" end
def global_scripts
def global_scripts <<-EOF moveProgressBar(percentDone) { nt.getElementById("rspec-header").style.width = percentDone +"%"; makeRed(element_id) { nt.getElementById(element_id).style.background = '#C40D0D'; nt.getElementById(element_id).style.color = '#FFFFFF'; makeYellow(element_id) { ement_id == "rspec-header" && document.getElementById(element_id).style.background != '#C40D0D') ment.getElementById(element_id).style.background = '#FAF834'; ment.getElementById(element_id).style.color = '#000000'; ment.getElementById(element_id).style.background = '#FAF834'; ment.getElementById(element_id).style.color = '#000000'; end
def global_styles
def global_styles <<-EOF eader { ound: #65C400; color: #fff; height: 4em; eport h1 { : 0px 10px 0px 10px; g: 10px; amily: "Lucida Grande", Helvetica, sans-serif; ize: 1.8em; on: absolute; { : 0; padding: 5px 10px; amily: "Lucida Grande", Helvetica, sans-serif; lign: right; px; 0px; right; p { : 0 0 0 2px; #totals { ize: 1.2em; _group { : 0 10px 5px; ound: #fff; : 0; padding: 0 0 5px; normal 11px "Lucida Grande", Helvetica, sans-serif; g: 3px; ound: #65C400; #fff; eight: bold; : 5px 0 5px 5px; g: 3px 3px 3px 18px; passed { -left: 5px solid #65C400; -bottom: 1px solid #65C400; ound: #DBFFB4; color: #3D7700; failed { -left: 5px solid #C20000; -bottom: 1px solid #C20000; #C20000; background: #FFFBD3; not_implemented { -left: 5px solid #FAF834; -bottom: 1px solid #FAF834; ound: #FCFB98; color: #131313; pending_fixed { -left: 5px solid #0000C2; -bottom: 1px solid #0000C2; #0000C2; background: #D3FBFF; ce { #000; ize: 12px; #BE5C00; code, style similar to vibrant ink */ ize: 12px; amily: monospace; white; ound-color: black; g: 0.1em 0 0.2em 0; eyword { color: #FF6600; } onstant { color: #339999; } ttribute { color: white; } lobal { color: white; } odule { color: white; } lass { color: white; } tring { color: #66FF00; } dent { color: white; } ethod { color: #FFCC00; } umber { color: white; } har { color: white; } omment { color: #9933CC; } ymbol { color: white; } egex { color: #44B4CC; } unct { color: white; } scape { color: white; } nterp { color: white; } xpr { color: white; } ffending { background-color: gray; } inenum { 75px; g: 0.1em 1em 0.2em 0; #000000; ound-color: #FFFBD3; end
def html_header
def html_header <<-EOF rsion="1.0" encoding="UTF-8"?> E html "-//W3C//DTD XHTML 1.0 Strict//EN" //www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> lns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> >RSpec results</title> http-equiv="Content-Type" content="text/html; charset=utf-8" /> http-equiv="Expires" content="-1" /> http-equiv="Pragma" content="no-cache" /> type="text/css"> in: 0; ing: 0; ground: #fff; -size: 80%; e> t type="text/javascript"> ![CDATA[ _scripts} ]> pt> type="text/css"> _styles} e> end
def initialize(output)
def initialize(output) super(output) @example_group_number = 0 @example_number = 0 @header_red = nil end
def message(message)
def message(message) end
def method_missing(m, *a, &b)
def method_missing(m, *a, &b) # no-op end
def move_progress
def move_progress @output.puts " <script type=\"text/javascript\">moveProgressBar('#{percent_done}');</script>" @output.flush end
def percent_done
def percent_done result = 100.0 if @example_count > 0 result = ((example_number).to_f / @example_count.to_f * 1000).to_i / 10.0 end result end
def report_header
def report_header <<-EOF ss="rspec-report"> "rspec-header"> d="label"> RSpec Code Examples</h1> d="summary"> d="totals"> </p> d="duration"> </p> ss="results"> end
def start(example_count)
def start(example_count) super(example_count) @output.puts html_header @output.puts report_header @output.flush end
def start_dump
def start_dump @output.puts " </dl>" @output.puts "</div>" @output.flush end