public function test_default_excludes_ignored() { $excludes = new Excludes(); $default_excludes = $excludes->get_default_excludes(); foreach ($default_excludes as $default_exclude) { $default_exclude = str_replace('*', rand(), $default_exclude); mkdir(trailingslashit($this->test_data) . $default_exclude); } $files = $this->backup->get_files(); $this->assertEquals(count($files), 3); }
public function main() { if ($this->_database === null) { $coverageDatabase = $this->project->getProperty('coverage.database'); if (!$coverageDatabase) { throw new BuildException('Either include coverage-setup in your build file or set ' . 'the "database" attribute'); } $database = new PhingFile($coverageDatabase); } else { $database = $this->_database; } $this->log('Calculating coverage threshold: min. ' . $this->_perProject . '% per project, ' . $this->_perClass . '% per class and ' . $this->_perMethod . '% per method is required'); $props = new Properties(); $props->load($database); foreach ($props->keys() as $filename) { $file = unserialize($props->getProperty($filename)); // Skip file if excluded from coverage threshold validation if ($this->_excludes !== null) { if (in_array($file['fullname'], $this->_excludes->getExcludedFiles())) { continue; } } $this->calculateCoverageThreshold($file['fullname'], $file['coverage']); } if ($this->_projectStatementCount > 0) { $coverage = $this->_projectStatementsCovered / $this->_projectStatementCount * 100; } else { $coverage = 0; } if ($coverage < $this->_perProject) { throw new BuildException('The coverage (' . round($coverage, 2) . '%) for the entire project ' . 'is lower than the specified threshold (' . $this->_perProject . '%)'); } $this->log('Passed coverage threshold. Minimum found coverage values are: ' . round($coverage, 2) . '% per project, ' . round($this->_minClassCoverageFound, 2) . '% per class and ' . round($this->_minMethodCoverageFound, 2) . '% per method'); }
/** * Calculates the coverage threshold * * @param string $filename The filename to analyse * @param array $coverageInformation Array with coverage information * * @throws BuildException */ protected function calculateCoverageThreshold($filename, $coverageInformation) { $classes = PHPUnitUtil::getDefinedClasses($filename, $this->_classpath); if (is_array($classes)) { foreach ($classes as $className) { // Skip class if excluded from coverage threshold validation if ($this->_excludes !== null) { if (in_array($className, $this->_excludes->getExcludedClasses())) { continue; } } $reflection = new ReflectionClass($className); $classStartLine = $reflection->getStartLine(); // Strange PHP5 reflection bug, classes without parent class // or implemented interfaces seem to start one line off if ($reflection->getParentClass() === null && count($reflection->getInterfaces()) === 0) { unset($coverageInformation[$classStartLine + 1]); } else { unset($coverageInformation[$classStartLine]); } reset($coverageInformation); $methods = $reflection->getMethods(); foreach ($methods as $method) { // PHP5 reflection considers methods of a parent class // to be part of a subclass, we don't if ($method->getDeclaringClass()->getName() != $reflection->getName()) { continue; } // Skip method if excluded from coverage threshold validation if ($this->_excludes !== null) { $excludedMethods = $this->_excludes->getExcludedMethods(); if (isset($excludedMethods[$className])) { if (in_array($method->getName(), $excludedMethods[$className]) || in_array($method->getName() . '()', $excludedMethods[$className])) { continue; } } } $methodStartLine = $method->getStartLine(); $methodEndLine = $method->getEndLine(); // small fix for XDEBUG_CC_UNUSED if (isset($coverageInformation[$methodStartLine])) { unset($coverageInformation[$methodStartLine]); } if (isset($coverageInformation[$methodEndLine])) { unset($coverageInformation[$methodEndLine]); } if ($method->isAbstract()) { continue; } $lineNr = key($coverageInformation); while ($lineNr !== null && $lineNr < $methodStartLine) { next($coverageInformation); $lineNr = key($coverageInformation); } $methodStatementsCovered = 0; $methodStatementCount = 0; while ($lineNr !== null && $lineNr <= $methodEndLine) { $methodStatementCount++; $lineCoverageInfo = $coverageInformation[$lineNr]; // set covered when CODE is other than -1 (not executed) if ($lineCoverageInfo > 0 || $lineCoverageInfo === -2) { $methodStatementsCovered++; } next($coverageInformation); $lineNr = key($coverageInformation); } if ($methodStatementCount > 0) { $methodCoverage = $methodStatementsCovered / $methodStatementCount * 100; } else { $methodCoverage = 0; } if ($methodCoverage < $this->_perMethod && !$method->isAbstract()) { throw new BuildException('The coverage (' . round($methodCoverage, 2) . '%) ' . 'for method "' . $method->getName() . '" is lower' . ' than the specified threshold (' . $this->_perMethod . '%), see file: "' . $filename . '"'); } elseif ($methodCoverage < $this->_perMethod && $method->isAbstract() && $this->_verbose === true) { $this->log('Skipped coverage threshold for abstract method "' . $method->getName() . '"'); } // store the minimum coverage value for logging (see #466) if ($this->_minMethodCoverageFound !== null) { if ($this->_minMethodCoverageFound > $methodCoverage) { $this->_minMethodCoverageFound = $methodCoverage; } } else { $this->_minMethodCoverageFound = $methodCoverage; } } $classStatementCount = count($coverageInformation); $classStatementsCovered = count(array_filter($coverageInformation, array($this, 'filterCovered'))); if ($classStatementCount > 0) { $classCoverage = $classStatementsCovered / $classStatementCount * 100; } else { $classCoverage = 0; } if ($classCoverage < $this->_perClass && !$reflection->isAbstract()) { throw new BuildException('The coverage (' . round($classCoverage, 2) . '%) for class "' . $reflection->getName() . '" is lower than the ' . 'specified threshold (' . $this->_perClass . '%), ' . 'see file: "' . $filename . '"'); } elseif ($classCoverage < $this->_perClass && $reflection->isAbstract() && $this->_verbose === true) { $this->log('Skipped coverage threshold for abstract class "' . $reflection->getName() . '"'); } // store the minimum coverage value for logging (see #466) if ($this->_minClassCoverageFound !== null) { if ($this->_minClassCoverageFound > $classCoverage) { $this->_minClassCoverageFound = $classCoverage; } } else { $this->_minClassCoverageFound = $classCoverage; } $this->_projectStatementCount += $classStatementCount; $this->_projectStatementsCovered += $classStatementsCovered; } } }
/** * File is excluded as a result of being in an excluded directory. * * Main test: Site_Size->filesize( $file ) * Expected: file size should be 0. */ public function test_file_size_excluded_via_parent_directory() { $file_path = $this->test_data . '/test-data.txt'; $file = new \SplFileInfo($file_path); // Check the file is created and its size is NOT 0. $this->assertContains($this->root->getPath(), $file->getPath()); $this->assertNotSame($file->getSize(), 0); // Exclude the parent directory, so the file in it is excluded by "inheritance" - file size should be 0. $excluded_dir_name = basename($file->getPath()); // test-data directory, the parent dir of the file. $excluded_dir = new Excludes($excluded_dir_name); $excluded_dir_site_size = new Site_Size('file', $excluded_dir); // Check the directory is excluded. File size in that directory should return 0. $this->assertContains($excluded_dir_name, $excluded_dir->get_user_excludes()); $this->assertSame($excluded_dir_site_size->filesize($file), 0); }
public function testBackUpDirIsExcludedWhenBackUpDirIsInRoot() { $excludes = new Excludes(); $this->assertContains(Path::get_root(), Path::get_path()); $this->assertContains(str_replace(trailingslashit(Path::get_root()), '', Path::get_path()), $excludes->get_excludes()); }
/** * File is NOT excluded directly (either in the root or any non-excluded sub-directory). * * Main test: Excludes->is_file_excluded( $file ) * Expected: false. */ public function test_non_excluded_file_is_excluded() { $file_path = $this->test_data . '/test-data.txt'; $file = new \SplFileInfo($file_path); // Check the file is created and its size is NOT 0. $this->assertContains($this->root->getPath(), $file->getPath()); $this->assertNotSame($file->getSize(), 0); // Do NOT exclude the parent directory, so the file in it is also non excluded by "inheritance". $non_excluded_dir_name = basename($file->getPath()); // test-data directory, the parent dir of the file. $non_excluded_dir = new Excludes(); // Check the directory is NOT excluded. File in that directory should be NOT excluded too. $this->assertNotContains($non_excluded_dir_name, $non_excluded_dir->get_user_excludes()); $this->assertFalse($non_excluded_dir->is_file_excluded($file)); }