text: # -*- coding: utf-8 -*-
  from xml.dom.minidom import Document
  
  from prospector.formatters.base import Formatter
  
  
  class XunitFormatter(Formatter):
  
      """
      This formatter outputs messages in the Xunit xml format, which is used by several
      CI tools to parse output. This formatter is therefore a compatability shim between tools built
      to use Xunit and prospector itself.
      """
  
      def render(self, summary=True, messages=True, profile=False):
          xml_doc = Document()
  
          testsuite_el = xml_doc.createElement("testsuite")
          testsuite_el.setAttribute("errors", str(self.summary["message_count"]))
          testsuite_el.setAttribute("failures", "0")
          testsuite_el.setAttribute("name", "prospector-%s" % "-".join(self.summary["tools"]))
          testsuite_el.setAttribute("tests", str(self.summary["message_count"]))
          testsuite_el.setAttribute("time", str(self.summary["time_taken"]))
          xml_doc.appendChild(testsuite_el)
  
          prop_el = xml_doc.createElement("properties")
          testsuite_el.appendChild(prop_el)
  
          sysout_el = xml_doc.createElement("system-out")
          sysout_el.appendChild(xml_doc.createCDATASection(""))
          testsuite_el.appendChild(sysout_el)
  
          syserr_el = xml_doc.createElement("system-err")
          syserr_el.appendChild(xml_doc.createCDATASection(""))
          testsuite_el.appendChild(syserr_el)
  
          for message in sorted(self.messages):
              testcase_el = xml_doc.createElement("testcase")
              testcase_el.setAttribute("name", "%s-%s" % (message.location.path, message.location.line))
  
              failure_el = xml_doc.createElement("error")
              failure_el.setAttribute("message", message.message.strip())
              failure_el.setAttribute("type", "%s Error" % message.source)
              template = "%(path)s:%(line)s: [%(code)s(%(source)s), %(function)s] %(message)s"
              cdata = template % {
                  "path": message.location.path,
                  "line": message.location.line,
                  "source": message.source,
                  "code": message.code,
                  "function": message.location.function,
                  "message": message.message.strip(),
              }
              failure_el.appendChild(xml_doc.createCDATASection(cdata))
  
              testcase_el.appendChild(failure_el)
  
              testsuite_el.appendChild(testcase_el)
  
          return xml_doc.toprettyxml()
  