Skip to content

Commit

Permalink
Merge branch 'add-junit-report' of https://github.com/bladeofsteel/PH…
Browse files Browse the repository at this point in the history
  • Loading branch information
gsherwood committed Sep 9, 2013
2 parents e8e01e4 + 5b91f70 commit bd64079
Show file tree
Hide file tree
Showing 5 changed files with 291 additions and 0 deletions.
1 change: 1 addition & 0 deletions CodeSniffer/CLI.php
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ public function processLongArgument($arg, $pos, $values)
'xml',
'json',
'checkstyle',
'junit',
'csv',
'emacs',
'notifysend',
Expand Down
135 changes: 135 additions & 0 deletions CodeSniffer/Reports/Junit.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
<?php
/**
* JUnit report for PHP_CodeSniffer.
*
* PHP version 5
*
* @category PHP
* @package PHP_CodeSniffer
* @author Gabriele Santini <[email protected]>
* @author Greg Sherwood <[email protected]>
* @author Oleg Lobach <[email protected]>
* @copyright 2009 SQLI <www.sqli.com>
* @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600)
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
* @link http://pear.php.net/package/PHP_CodeSniffer
*/

/**
* JUnit report for PHP_CodeSniffer.
*
* PHP version 5
*
* @category PHP
* @package PHP_CodeSniffer
* @author Gabriele Santini <[email protected]>
* @author Greg Sherwood <[email protected]>
* @author Oleg Lobach <[email protected]>
* @copyright 2009 SQLI <www.sqli.com>
* @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600)
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
* @version Release: @package_version@
* @link http://pear.php.net/package/PHP_CodeSniffer
*/
class PHP_CodeSniffer_Reports_Junit implements PHP_CodeSniffer_Report
{


/**
* Prints all violations for processed files, in a JUnit format.
*
* Violations are grouped by file.
*
* @param array $report Prepared report.
* @param boolean $showSources Show sources?
* @param int $width Maximum allowed lne width.
* @param boolean $toScreen Is the report being printed to screen?
*
* @return string
*/
public function generate(
$report,
$showSources=false,
$width=80,
$toScreen=true
) {
$errors = 0;
$tests = 0;
foreach ($report['files'] as $file) {
if (count($file['messages']) === 0) {
++$tests;
continue;
}
$errors += $file['errors'] + $file['warnings'];
$tests += $file['errors'] + $file['warnings'];
}

$out = new XMLWriter;
$out->openMemory();
$out->setIndent(true);
$out->startDocument('1.0', 'UTF-8');

$out->startElement('testsuites');
$out->writeAttribute('name', 'PHP_CodeSniffer @package_version@');
$out->writeAttribute('tests', $tests);
$out->writeAttribute('failures', $errors);

$errorsShown = 0;
foreach ($report['files'] as $filename => $file) {
$out->startElement('testsuite');
$out->writeAttribute('name', $filename);

if (count($file['messages']) === 0) {
$out->writeAttribute('tests', 1);
$out->writeAttribute('failures', 0);

$out->startElement('testcase');
$out->writeAttribute('name', $filename);
$out->endElement();

$out->endElement();
continue;
}

$failures = $file['errors'] + $file['warnings'];
$out->writeAttribute('tests', $failures);
$out->writeAttribute('failures', $failures);

foreach ($file['messages'] as $line => $lineErrors) {
foreach ($lineErrors as $column => $colErrors) {
foreach ($colErrors as $error) {
$out->startElement('testcase');
$out->writeAttribute('name', $error['source'] . " at $filename ($line:$column)");

$error['type'] = strtolower($error['type']);
if (PHP_CODESNIFFER_ENCODING !== 'utf-8') {
$error['message'] = iconv(PHP_CODESNIFFER_ENCODING, 'utf-8', $error['message']);
}

$out->startElement('failure');
$out->writeAttribute('type', $error['type']);
$out->writeAttribute('message', $error['message']);
$out->endElement();

$out->endElement();

$errorsShown++;
}
}
}//end foreach

$out->endElement();

}//end foreach

$out->endElement();
echo $out->flush();

return $errorsShown;

}//end generate()


}//end class

?>
2 changes: 2 additions & 0 deletions tests/Core/AllTests.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
require_once 'Reports/SvnblameTest.php';
require_once 'Reports/GitblameTest.php';
require_once 'Reports/HgblameTest.php';
require_once 'Reports/JunitTest.php';

if (is_file(dirname(__FILE__).'/../../CodeSniffer.php') === true) {
// We are not installed.
Expand Down Expand Up @@ -90,6 +91,7 @@ public static function suite()
$suite->addTestSuite('Core_Reports_SvnblameTest');
$suite->addTestSuite('Core_Reports_GitblameTest');
$suite->addTestSuite('Core_Reports_HgblameTest');
$suite->addTestSuite('Core_Reports_JunitTest');
return $suite;

}//end suite()
Expand Down
62 changes: 62 additions & 0 deletions tests/Core/Reports/JunitTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php
/**
* Tests for the JUnit report.
*
* PHP version 5
*
* @category PHP
* @package PHP_CodeSniffer
* @author Gabriele Santini <[email protected]>
* @author Greg Sherwood <[email protected]>
* @author Oleg Lobach <[email protected]>
* @copyright 2009 SQLI <www.sqli.com>
* @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600)
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
* @link http://pear.php.net/package/PHP_CodeSniffer
*/

require_once 'PHPUnit/Framework/TestCase.php';
require_once dirname(__FILE__).'/AbstractTestCase.php';

/**
* Tests for the Checkstyle report.
*
* @category PHP
* @package PHP_CodeSniffer
* @author Gabriele Santini <[email protected]>
* @author Greg Sherwood <[email protected]>
* @author Oleg Lobach <[email protected]>
* @copyright 2009 SQLI <www.sqli.com>
* @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600)
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
* @version Release: @package_version@
* @link http://pear.php.net/package/PHP_CodeSniffer
*/
class Core_Reports_JunitTest extends Core_Reports_AbstractTestCase
{


/**
* Tests standard report.
*
* @return void
*/
public function testGenerate()
{
$junitReport = new PHP_CodeSniffer_Reports_Junit();
$generated = $this->getFixtureReport($junitReport);
$xmlDocument = new DOMDocument();

$xmlDocument->loadXML($generated);
$result = $xmlDocument->schemaValidate(
dirname(__FILE__).'/XSD/Junit.xsd'
);

$this->assertTrue($result);

}//end testGenerate()


}//end class

?>
91 changes: 91 additions & 0 deletions tests/Core/Reports/XSD/Junit.xsd
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="failure">
<xs:complexType mixed="true">
<xs:attribute name="type" type="xs:string" use="optional"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>

<xs:element name="error">
<xs:complexType mixed="true">
<xs:attribute name="type" type="xs:string" use="optional"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>

<xs:element name="properties">
<xs:complexType>
<xs:sequence>
<xs:element ref="property" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>

<xs:element name="property">
<xs:complexType>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="value" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>

<xs:element name="skipped" type="xs:string"/>
<xs:element name="system-err" type="xs:string"/>
<xs:element name="system-out" type="xs:string"/>

<xs:element name="testcase">
<xs:complexType>
<xs:sequence>
<xs:element ref="skipped" minOccurs="0" maxOccurs="1"/>
<xs:element ref="error" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="failure" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="system-out" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="system-err" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="assertions" type="xs:string" use="optional"/>
<xs:attribute name="time" type="xs:string" use="optional"/>
<xs:attribute name="classname" type="xs:string" use="optional"/>
<xs:attribute name="status" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>

<xs:element name="testsuite">
<xs:complexType>
<xs:sequence>
<xs:element ref="properties" minOccurs="0" maxOccurs="1"/>
<xs:element ref="testcase" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="system-out" minOccurs="0" maxOccurs="1"/>
<xs:element ref="system-err" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="tests" type="xs:string" use="required"/>
<xs:attribute name="failures" type="xs:string" use="optional"/>
<xs:attribute name="errors" type="xs:string" use="optional"/>
<xs:attribute name="time" type="xs:string" use="optional"/>
<xs:attribute name="disabled" type="xs:string" use="optional"/>
<xs:attribute name="skipped" type="xs:string" use="optional"/>
<xs:attribute name="timestamp" type="xs:string" use="optional"/>
<xs:attribute name="hostname" type="xs:string" use="optional"/>
<xs:attribute name="id" type="xs:string" use="optional"/>
<xs:attribute name="package" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>

<xs:element name="testsuites">
<xs:complexType>
<xs:sequence>
<xs:element ref="testsuite" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="optional"/>
<xs:attribute name="time" type="xs:string" use="optional"/>
<xs:attribute name="tests" type="xs:string" use="optional"/>
<xs:attribute name="failures" type="xs:string" use="optional"/>
<xs:attribute name="disabled" type="xs:string" use="optional"/>
<xs:attribute name="errors" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>


</xs:schema>

0 comments on commit bd64079

Please sign in to comment.