Module: Teaspoon::Formatter::RspecHtml::Templates

Defined in:
lib/teaspoon/formatter/rspec_html.rb

Constant Summary collapse

CSS =
"body {\n  margin: 0;\n  padding: 0;\n  background: #fff;\n  font-size: 80%;\n}\n\n#teaspoon-header {\n  background: #65C400;\n  color: #fff;\n  height: 4em;\n}\n\n.teaspoon-report h1 {\n  margin: 0px 10px 0px 10px;\n  padding: 10px;\n  font-family: \"Lucida Grande\", Helvetica, sans-serif;\n  font-size: 1.8em;\n  position: absolute;\n}\n\n#label {\n  float: left;\n}\n\n#display-filters {\n  float: left;\n  padding: 28px 0 0 40%;\n  font-family: \"Lucida Grande\", Helvetica, sans-serif;\n}\n\n#summary {\n  float: right;\n  padding: 5px 10px;\n  font-family: \"Lucida Grande\", Helvetica, sans-serif;\n  text-align: right;\n}\n\n#summary p {\n  margin: 0 0 0 2px;\n}\n\n#summary #totals {\n  font-size: 1.2em;\n}\n\n.example_group {\n  background: #fff;\n}\n\n.results > .example_group {\n  margin: 0 10px 5px;\n}\n\ndl {\n  font: normal 11px \"Lucida Grande\", Helvetica, sans-serif;\n}\n\n.results > .example_group > dl {\n  margin: 0;\n  padding: 0 0 5px;\n}\n\n.results > .example_group > dl dl {\n  margin-left: 15px;\n}\n\ndt {\n  padding: 3px;\n  background: #65C400;\n  color: #fff;\n  font-weight: bold;\n}\n\ndd {\n  margin: 5px 0 5px 5px;\n  padding: 3px 3px 3px 18px;\n}\n\ndd .duration {\n  padding-left: 5px;\n  text-align: right;\n  right: 0px;\n  float: right;\n}\n\ndd.example.passed {\n  border-left: 5px solid #65C400;\n  border-bottom: 1px solid #65C400;\n  background: #DBFFB4; color: #3D7700;\n}\n\ndd.example.pending {\n  border-left: 5px solid #FAF834;\n  border-bottom: 1px solid #FAF834;\n  background: #FCFB98; color: #131313;\n}\n\ndd.example.failed {\n  border-left: 5px solid #C20000;\n  border-bottom: 1px solid #C20000;\n  color: #C20000; background: #FFFBD3;\n}\n\ndt.pending {\n  color: #000000; background: #FAF834;\n}\n\ndt.failed {\n  color: #FFFFFF; background: #C40D0D;\n}\n\n#teaspoon-header.pending {\n  color: #000000; background: #FAF834;\n}\n\n#teaspoon-header.failed {\n  color: #FFFFFF; background: #C40D0D;\n}\n".strip_heredoc
JAVASCRIPT =
"(function() {\n  \"use strict\";\n\n  if (!document.querySelectorAll) {\n    alert(\"Warning: Your browser does not support document.querySelectorAll. Your report may not work properly.\");\n    return;\n  }\n\n  function get(id) {\n    return document.getElementById(id);\n  }\n\n  function getAll(scope, selector) {\n    if (arguments.length === 1) {\n      selector = scope;\n      scope = document;\n    }\n\n    return scope.querySelectorAll(selector);\n  }\n\n  function show(element) {\n    if (element.oldDisplayValue) {\n      element.style.display = element.oldDisplayValue;\n    } else {\n      element.style.display = \"\";\n    }\n  }\n\n  function hide(element) {\n    if (element.style.display === \"none\") {\n      return;\n    }\n\n    if (element.oldDisplayValue === undefined) {\n      element.oldDisplayValue = element.style.display;\n    }\n\n    element.style.display = \"none\";\n  }\n\n  function showAll(elements) {\n    for (var i = 0; i < elements.length; i++) {\n      show(elements[i]);\n    }\n  }\n\n  function hideAll(elements) {\n    for (var i = 0; i < elements.length; i++) {\n      hide(elements[i]);\n    }\n  }\n\n  function toggleAll(elements, display) {\n    if (display) {\n      showAll(elements);\n    } else {\n      hideAll(elements);\n    }\n  }\n\n  function isHidden(element) {\n    return element.style.display === \"none\";\n  }\n\n  function isAllHidden(elements) {\n    var allHidden = true;\n\n    for (var i = 0; i < elements.length; i++) {\n      if (!isHidden(elements[i])) {\n        allHidden = false;\n        break;\n      }\n    }\n\n    return allHidden;\n  }\n\n  function setText(element, text) {\n    while (element.firstChild !== null) {\n      element.removeChild(element.firstChild);\n    }\n\n    element.appendChild(document.createTextNode(text));\n  }\n\n  function addClass(element, className) {\n    element.className += \" \" + className;\n  }\n\n  function addClassAll(elements, className) {\n    for (var i = 0; i < elements.length; i++) {\n      addClass(elements[i], className);\n    }\n  }\n\n  function hasClass(element, className) {\n    return (\" \" + element.className + \" \").replace(/[\\\\t\\\\r\\\\n\\\\f]/g, \" \").indexOf(\" \" + className + \" \") >= 0;\n  }\n\n  function isTag(element, tagName) {\n    return element.tagName && element.tagName.toLowerCase() === tagName;\n  }\n\n  function parents(elements, predicate) {\n    var results = [];\n\n    for (var i = 0; i < elements.length; i++) {\n      var parent = elements[i].parentNode;\n\n      while (parent) {\n        if (predicate(parent)) {\n          results.push(parent);\n        }\n\n        parent = parent.parentNode;\n      }\n    }\n\n    return results;\n  }\n\n  function children(elements, predicate) {\n    var results = [];\n\n    for (var i = 0; i < elements.length; i++) {\n      if (!elements[i].hasChildNodes()) {\n        continue;\n      }\n\n      for (var j = 0; j < elements[i].childNodes.length; j++) {\n        if (predicate(elements[i].childNodes[j])) {\n          results.push(elements[i].childNodes[j]);\n        }\n      }\n    }\n\n    return results;\n  }\n\n  var elements = getAll(\"input[data-class-filter]\");\n\n  function handleClassFilterChange(e) {\n    var element = e.target || e.srcElement;\n    showAll(getAll(\".example_group\"));\n    toggleAll(getAll(\".example.\" + element.getAttribute(\"data-type\")), element.checked);\n\n    var groups = getAll(\".example_group\");\n\n    for (var i = 0; i < groups.length; i++) {\n      if (isAllHidden(getAll(groups[i], \".example\"))) {\n        hide(groups[i]);\n      }\n    }\n  }\n\n  for (var i = 0; i < elements.length; i++) {\n    elements[i].onchange = handleClassFilterChange;\n  }\n\n  get(\"duration\").innerHTML = \"Finished in <strong></strong>\";\n  setText(getAll(\"#duration strong\")[0], get(\"duration-value\").value + \" seconds\");\n  get(\"totals\").innerHTML = '<span class=\"total-amount\"></span> examples, <span class=\"failure-amount\"></span> failures, <span class=\"pending-amount\"></span> pending';\n  var failureAmount = getAll(\".example.failed\").length;\n  var pendingAmount = getAll(\".example.pending\").length;\n  setText(getAll(\"#totals .total-amount\")[0], getAll(\".example\").length);\n  setText(getAll(\"#totals .failure-amount\")[0], failureAmount);\n  setText(getAll(\"#totals .pending-amount\")[0], pendingAmount);\n\n  if (failureAmount > 0) {\n    addClass(get(\"teaspoon-header\"), \"failed\");\n  } else if (pendingAmount > 0) {\n    addClass(get(\"teaspoon-header\"), \"pending\");\n  }\n\n  function propagateClass(exampleSelector, groupPredicate, classToAdd) {\n    var exampleElements = getAll(exampleSelector);\n\n    var groupElements = parents(exampleElements, function(p) {\n      return hasClass(p, \"example_group\") && groupPredicate(p);\n    });\n\n    addClassAll(groupElements, classToAdd);\n    var dlChildren = children(groupElements, function(c) { return isTag(c, \"dl\"); });\n    var dtChildren = children(dlChildren, function(c) { return isTag(c, \"dt\"); });\n    addClassAll(dtChildren, classToAdd);\n  }\n\n  propagateClass(\".example.failed\", function() { return true; }, \"failed\");\n  propagateClass(\".example.pending\", function(p) { return !hasClass(p, \"failed\"); }, \"pending\");\n  propagateClass(\".example\", function(p) { return !hasClass(p, \"failed\") && !hasClass(p, \"pending\"); }, \"passed\");\n})();\n".strip_heredoc
HEADER =
"<!DOCTYPE html>\n<html>\n  <head>\n    <title>Teaspoon results</title>\n\n    <style type=\"text/css\">\n      \#{CSS}\n    </style>\n  </head>\n\n  <body>\n    <div class=\"teaspoon-report\">\n      <div id=\"teaspoon-header\">\n        <div id=\"label\">\n          <h1>Teaspoon Code Examples</h1>\n        </div>\n\n        <div id=\"display-filters\">\n          <input id=\"passed-checkbox\" data-class-filter data-type=\"passed\" type=\"checkbox\" checked=\"checked\">\n          <label for=\"passed-checkbox\">Passed</label>\n          <input id=\"failed-checkbox\" data-class-filter data-type=\"failed\" type=\"checkbox\" checked=\"checked\">\n          <label for=\"failed-checkbox\">Failed</label>\n          <input id=\"pending-checkbox\" data-class-filter data-type=\"pending\" type=\"checkbox\" checked=\"checked\">\n          <label for=\"pending-checkbox\">Pending</label>\n        </div>\n\n        <div id=\"summary\">\n          <p id=\"totals\">&nbsp;</p>\n          <p id=\"duration\">&nbsp;</p>\n        </div>\n      </div>\n\n      <div class=\"results\">\n".strip_heredoc
SUITE_START =
"<div class=\"example_group\">\n  <dl>\n    <dt><%= h @o.label %></dt>\n".strip_heredoc
SPEC =
"<dd class=\"example <%= h @o.status %>\">\n  <span class=\"spec-name\"><%= h @o.label %></span>\n  <span class=\"duration\"><%= h \"\\\#{@o.elapsed}s\" if @o.elapsed %></span>\n\n  <% if @o.failing? %>\n    <div class=\"message\">\n      <pre><%= h @o.trace %></pre>\n    </div>\n  <% end %>\n</dd>\n".strip_heredoc
SUITE_END =
"  </dl>\n</div>\n".strip_heredoc
"      </div>\n    </div>\n\n    <input type=\"hidden\" id=\"duration-value\" value=\"<%= h @o.elapsed %>\" />\n\n    <script type=\"text/javascript\">\n      \#{JAVASCRIPT}\n    </script>\n  </body>\n</html>\n".strip_heredoc