opal/opal/rspec/browser_formatter.rb in opal-rspec-0.3.0.beta1 vs opal/opal/rspec/browser_formatter.rb in opal-rspec-0.3.0.beta2
- old
+ new
@@ -1,85 +1,99 @@
+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
+ duration = sprintf("%0.5f", example.execution_result[:run_time])
- @example_group_failed = true
-
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')
+ @example_group_failed = true
- 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_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}s</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}s</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
' '
end
def long_padding
@@ -87,10 +101,14 @@
end
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)`
else
@native = el
@@ -139,56 +157,32 @@
def append_to_head
`document.getElementsByTagName('head')[0].appendChild(#@native)`
end
end
- CSS_STYLES = <<-EOF
-body {
- font-size: 14px;
- font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
-}
+ REPORT_TEMPLATE = <<-EOF
+<div class="rspec-report">
-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;
+ <div id="rspec-header">
+ <div id="label">
+ <h1>RSpec Code Examples</h1>
+ </div>
- 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;
-}
+ <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>
-ul.example_groups {
- list-style-type: none;
-}
+ <div id="summary">
+ <p id="totals"> </p>
+ <p id="duration"> </p>
+ </div>
+ </div>
-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;
-}
+ <div id="rspec-results" class="results">
+ </div>
+</div>
EOF
end
end
end