diff --git a/src/ParaTest/Logging/JUnit/Writer.php b/src/ParaTest/Logging/JUnit/Writer.php index 06ddffba..280683b4 100644 --- a/src/ParaTest/Logging/JUnit/Writer.php +++ b/src/ParaTest/Logging/JUnit/Writer.php @@ -133,6 +133,9 @@ protected function appendCase($suiteNode, TestCase $case) $vars = get_object_vars($case); foreach ($vars as $name => $value) { if (preg_match(static::$caseAttrs, $name)) { + if ($this->isEmptyLineAttribute($name, $value)) { + continue; + } $caseNode->setAttribute($name, $value); } } @@ -198,4 +201,15 @@ protected function getSuiteRootAttributes($suites) return $result; }, array_merge(array('name' => $this->name), self::$defaultSuite)); } + + /** + * Prevent writing empty "line" XML attributes which could break parsers. + * @param string $name + * @param mixed $value + * @return bool + */ + private function isEmptyLineAttribute($name, $value) + { + return $name === 'line' && empty($value); + } } diff --git a/test/fixtures/results/junit-example-result.xml b/test/fixtures/results/junit-example-result.xml new file mode 100644 index 00000000..efcb763f --- /dev/null +++ b/test/fixtures/results/junit-example-result.xml @@ -0,0 +1,36 @@ + + + + + + + UnitTestWithClassAnnotationTest::testFalsehood + Failed asserting that true is false. + + /home/brian/Projects/parallel-phpunit/test/fixtures/tests/UnitTestWithClassAnnotationTest.php:20 + + + + + + + UnitTestWithErrorTest::testTruth + Exception: Error!!! + + /home/brian/Projects/parallel-phpunit/test/fixtures/tests/UnitTestWithErrorTest.php:12 + + + + + + + UnitTestWithMethodAnnotationsTest::testFalsehood + Failed asserting that true is false. + + /home/brian/Projects/parallel-phpunit/test/fixtures/tests/UnitTestWithMethodAnnotationsTest.php:18 + + + + + + diff --git a/test/unit/ParaTest/Logging/JUnit/WriterTest.php b/test/unit/ParaTest/Logging/JUnit/WriterTest.php index 139cd845..ce0ec152 100644 --- a/test/unit/ParaTest/Logging/JUnit/WriterTest.php +++ b/test/unit/ParaTest/Logging/JUnit/WriterTest.php @@ -5,19 +5,24 @@ class WriterTest extends \TestBase { protected $writer; + + /** @var LogInterpreter */ protected $interpreter; protected $passing; public function setUp() { $this->interpreter = new LogInterpreter(); - $this->writer = new Writer($this->interpreter, "test/fixtures/tests/"); + $this->writer = new Writer($this->interpreter, "test/fixtures/tests/"); $this->passing = FIXTURES . DS . 'results' . DS . 'single-passing.xml'; } public function testConstructor() { - $this->assertInstanceOf('ParaTest\\Logging\\LogInterpreter', $this->getObjectValue($this->writer, 'interpreter')); + $this->assertInstanceOf( + 'ParaTest\\Logging\\LogInterpreter', + $this->getObjectValue($this->writer, 'interpreter') + ); $this->assertEquals("test/fixtures/tests/", $this->writer->getName()); } @@ -44,12 +49,29 @@ public function testWrite() $this->addPassingReader(); $this->writer->write($output); $this->assertXmlStringEqualsXmlString(file_get_contents($this->passing), file_get_contents($output)); - if(file_exists($output)) unlink($output); + if (file_exists($output)) { + unlink($output); + } } protected function addPassingReader() { $reader = new Reader($this->passing); - $this->interpreter->addReader($reader); + $this->interpreter->addReader($reader); + } + + /** + * Empty line attributes, e.g. line="" breaks Jenkins parsing since it needs to be an integer. + * To repair, ensure that empty line attributes are actually written as 0 instead of empty string. + */ + public function testThatEmptyLineAttributesConvertToZero() + { + $mixed = FIXTURES . DS . 'results' . DS . 'junit-example-result.xml'; + $reader = new Reader($mixed); + $this->interpreter->addReader($reader); + $writer = new Writer($this->interpreter, "test/fixtures/tests/"); + $xml = $writer->getXml(); + + $this->assertFalse(strpos($xml, 'line=""'), 'Expected no empty line attributes (line=""), but found one.'); } -} \ No newline at end of file +}