diff --git a/src/CodeCoverage/Report/Factory.php b/src/CodeCoverage/Report/Factory.php index 72b974a84..bcd043140 100644 --- a/src/CodeCoverage/Report/Factory.php +++ b/src/CodeCoverage/Report/Factory.php @@ -277,6 +277,28 @@ private function reducePaths(&$files) ksort($files); - return substr($commonPath, 0, -1); + return $this->removeTailingDirectorySeparator($commonPath); + } + + /** + * @param $commonPath + * @return bool + */ + private function isNotRoot($commonPath) + { + return strlen($commonPath) > 1; + } + + /** + * @param $commonPath + * @return string + */ + private function removeTailingDirectorySeparator($commonPath) + { + if ($this->isNotRoot($commonPath)) { + $commonPath = substr($commonPath, 0, -1); + return $commonPath; + } + return $commonPath; } } diff --git a/src/CodeCoverage/Report/Node.php b/src/CodeCoverage/Report/Node.php index d4084317b..ef76ef0c4 100644 --- a/src/CodeCoverage/Report/Node.php +++ b/src/CodeCoverage/Report/Node.php @@ -89,7 +89,7 @@ abstract class PHP_CodeCoverage_Report_Node implements Countable */ public function __construct($name, PHP_CodeCoverage_Report_Node $parent = null) { - if (substr($name, -1) == '/') { + if ($this->hasTailingSlashAndIsNotRoot($name)) { $name = substr($name, 0, -1); } @@ -377,4 +377,13 @@ abstract public function getNumFunctions(); * @return integer */ abstract public function getNumTestedFunctions(); + + /** + * @param $name + * @return bool + */ + private function hasTailingSlashAndIsNotRoot($name) + { + return substr($name, -1) == '/' && strlen($name) > 1; + } } diff --git a/tests/PHP/CodeCoverage/Report/FactoryTest.php b/tests/PHP/CodeCoverage/Report/FactoryTest.php index 12b4f67f1..e2e77b07c 100644 --- a/tests/PHP/CodeCoverage/Report/FactoryTest.php +++ b/tests/PHP/CodeCoverage/Report/FactoryTest.php @@ -231,6 +231,17 @@ public function reducePathsProvider() '/home/sb/Money/MoneyBag.php' => array() ) ), + array( + array( + 'driveA/Money.php' => array(), + 'driveB/MoneyBag.php' => array() + ), + '/', + array( + '/driveA/Money.php' => array(), + '/driveB/MoneyBag.php' => array() + ) + ), array( array( 'Money.php' => array() diff --git a/tests/PHP/CodeCoverage/Report/NodeTest.php b/tests/PHP/CodeCoverage/Report/NodeTest.php new file mode 100644 index 000000000..78c244e24 --- /dev/null +++ b/tests/PHP/CodeCoverage/Report/NodeTest.php @@ -0,0 +1,98 @@ +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @category PHP + * @package CodeCoverage + * @subpackage Tests + * @author Sebastian Bergmann + * @copyright 2009-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/php-code-coverage + */ + +/** + * Tests for the PHP_CodeCoverage_Report_Node class. + * + * @category PHP + * @package CodeCoverage + * @subpackage Tests + * @author Sebastian Bergmann + * @copyright 2009-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/php-code-coverage + */ +class PHP_CodeCoverage_Report_NodeTest extends PHPUnit_Framework_TestCase +{ + public function testTrimsTailingSlashes() + { + $node = $this->getInstance('/SomeName.php/'); + $this->assertEquals('/SomeName.php', $node->getPath()); + } + + public function testNodeAcceptsRootScope() + { + $node = $this->getInstance('/'); + $this->assertEquals('/', $node->getPath()); + } + + /** + * @param $path + * @return PHP_CodeCoverage_Report_Node + */ + private function getInstance($path) + { + $builder = $this->getMockBuilder('PHP_CodeCoverage_Report_Node') + ->setConstructorArgs(array($path)); + + $this->mockMethods($builder); + return $builder->getMock(); + } + + /** + * @param $builder + */ + private function mockMethods($builder) + { + $reflectionClass = new \ReflectionClass('PHP_CodeCoverage_Report_Node'); + $methods = array(); + foreach ($reflectionClass->getMethods() as $method) { + if ($method->isAbstract()) { + $methods[] = $method->getName(); + } + } + $builder->setMethods($methods); + } +}