Skip to content

Commit

Permalink
Use html printer code from rspec directly (nicer output)
Browse files Browse the repository at this point in the history
  • Loading branch information
adambeynon committed Dec 17, 2013
1 parent d813ddb commit e448fe7
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 82 deletions.
1 change: 1 addition & 0 deletions app/rspec-builder.rb
Expand Up @@ -38,6 +38,7 @@

# we want access to BaseFormatter
require 'rspec/core/formatters/base_formatter'
require 'rspec/core/formatters/html_printer'

# For now, we don't support mocking. This placeholder in rspec-core allows that.
require 'rspec/core/mocking/with_rspec'
2 changes: 0 additions & 2 deletions config.ru
@@ -1,8 +1,6 @@
require 'bundler'
Bundler.require

require 'opal-sprockets'

Opal::Processor.source_map_enabled = false

run Opal::Server.new { |s|
Expand Down
2 changes: 1 addition & 1 deletion opal-rspec.gemspec
Expand Up @@ -15,7 +15,7 @@ Gem::Specification.new do |s|

s.require_paths = ['lib']

s.add_dependency 'opal', '~> 0.6.0'
s.add_dependency 'opal', ['>= 0.5.0', '< 1.0.0']

s.add_development_dependency 'rake'
end
Expand Down
152 changes: 73 additions & 79 deletions opal/opal/rspec/browser_formatter.rb
@@ -1,81 +1,95 @@
require 'erb'

module Opal
module RSpec
class BrowserFormatter < ::RSpec::Core::Formatters::BaseFormatter
include ERB::Util

CSS_STYLES = ::RSpec::Core::Formatters::HtmlPrinter::GLOBAL_STYLES

def start(example_count)
super

@summary_element = Element.new(:p, class_name: 'summary', text: 'Runner...')
@groups_element = Element.new(:ul, class_name: 'example_groups')

target = Element.new(`document.body`)
target << @summary_element
target << @groups_element
target << Element.new(:div, html: REPORT_TEMPLATE)
@rspec_results = Element.id('rspec-results')

styles = Element.new(:style, type: 'text/css', css_text: CSS_STYLES)
css_text = CSS_STYLES + "\n body { padding: 0; margin: 0 }"
styles = Element.new(:style, type: 'text/css', css_text: css_text)
styles.append_to_head
end

def example_group_started(example_group)
super

@example_group_failed = false
@group_element = Element.new(:li, class_name: 'group passed')
parents = example_group.parent_groups.size

description = Element.new(:span, class_name: 'group_description', text: example_group.description)
@group_element << description
@rspec_group = Element.new(:div, class_name: "example_group passed")
@rspec_dl = Element.new(:dl)
@rspec_dt = Element.new(:dt, class_name: "passed", text: example_group.description)
@rspec_group << @rspec_dl
@rspec_dl << @rspec_dt

@example_list = Element.new(:ul, class_name: 'examples')
@group_element << @example_list
@rspec_dl.style 'margin-left', "#{(parents - 2) * 15}px"

@groups_element << @group_element
@rspec_results << @rspec_group
end

def example_group_finished(example_group)
super

if @example_group_failed
@group_element.class_name = 'group failed'
@rspec_group.class_name = "example_group failed"
@rspec_dt.class_name = "failed"
Element.id('rspec-header').class_name = 'failed'
end
end

def example_failed(example)
super

@example_group_failed = true
duration = sprintf("%0.5f", example.execution_result[:run_time])

error = example.execution_result[:exception]
error_name = error.class.name.to_s
output = "#{short_padding}#{error_name}:\n"
error.message.to_s.split("\n").each { |line| output += "#{long_padding} #{line}\n" }

wrapper = Element.new(:li, class_name: 'example failed')

description = Element.new(:span, class_name: 'example_description', text: example.description)
wrapper << description

exception = Element.new(:pre, class_name: 'exception', text: output)
wrapper << exception
@example_group_failed = true

@example_list << wrapper
@example_list.style :display, 'list-item'
@rspec_dl << Element.new(:dd, class_name: "example failed", html: <<-HTML)
<span class="failed_spec_name">#{h example.description}</span>
<span class="duration">#{duration}</span>
<div class="failure">
<div class="message"><pre>#{h output}</pre></div>
</div>
HTML
end

def example_passed(example)
super
duration = sprintf("%0.5f", example.execution_result[:run_time])

wrapper = Element.new(:li, class_name: 'example passed')
description = Element.new(:span, class_name: 'example_description', text: example.description)

wrapper << description
@example_list << wrapper
@rspec_dl << Element.new(:dd, class_name: "example passed", html: <<-HTML)
<span class="passed_spec_name">#{h example.description}</span>
<span class="duration">#{duration}</span>
HTML
end

def dump_summary(duration, example_count, failure_count, pending_count)
super

summary = "\n#{example_count} examples, #{failure_count} failures (time taken: #{duration})"
@summary_element.text = summary
totals = "#{example_count} examples, #{failure_count} failures"
Element.id('totals').html = totals

duration = "Finished in <strong>#{sprintf("%.5f", duration)} seconds</strong>"
Element.id('duration').html = duration

add_scripts
end

def add_scripts
content = ::RSpec::Core::Formatters::HtmlPrinter::GLOBAL_SCRIPTS
`window.eval(#{content})`
end

def short_padding
Expand All @@ -89,6 +103,10 @@ def long_padding
class Element
attr_reader :native

def self.id(id)
new(`document.getElementById(id)`)
end

def initialize(el, attrs={})
if String === el
@native = `document.createElement(el)`
Expand Down Expand Up @@ -141,53 +159,29 @@ def append_to_head
end
end

CSS_STYLES = <<-EOF
body {
font-size: 14px;
font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
}
pre {
font-family: "Bitstream Vera Sans Mono", Monaco, "Lucida Console", monospace;
font-size: 12px;
color: #444444;
white-space: pre;
padding: 3px 0px 3px 12px;
margin: 0px 0px 8px;
background: #FAFAFA;
-webkit-box-shadow: rgba(0,0,0,0.07) 0 1px 2px inset;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
border: 1px solid #DDDDDD;
}
ul.example_groups {
list-style-type: none;
}
li.group.passed .group_description {
color: #597800;
font-weight: bold;
}
li.group.failed .group_description {
color: #FF000E;
font-weight: bold;
}
li.example.passed {
color: #597800;
}
li.example.failed {
color: #FF000E;
}
.examples {
list-style-type: none;
}
REPORT_TEMPLATE = <<-EOF
<div class="rspec-report">
<div id="rspec-header">
<div id="label">
<h1>RSpec Code Examples</h1>
</div>
<div id="display-filters">
<input id="passed_checkbox" name="passed_checkbox" type="checkbox" checked="checked" onchange="apply_filters()" value="1" /> <label for="passed_checkbox">Passed</label>
<input id="failed_checkbox" name="failed_checkbox" type="checkbox" checked="checked" onchange="apply_filters()" value="2" /> <label for="failed_checkbox">Failed</label>
<input id="pending_checkbox" name="pending_checkbox" type="checkbox" checked="checked" onchange="apply_filters()" value="3" /> <label for="pending_checkbox">Pending</label>
</div>
<div id="summary">
<p id="totals">&#160;</p>
<p id="duration">&#160;</p>
</div>
</div>
<div id="rspec-results" class="results">
</div>
</div>
EOF
end
end
Expand Down

0 comments on commit e448fe7

Please sign in to comment.