Changeset View
Changeset View
Standalone View
Standalone View
src/unit/engine/CSharpToolsTestEngine.php
| Show First 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | if ($this->cscoverHintPath === null) { | ||||
| "Unable to locate cscover. Configure it with ". | "Unable to locate cscover. Configure it with ". | ||||
| "the `unit.csharp.coverage.binary' option in .arcconfig"); | "the `unit.csharp.coverage.binary' option in .arcconfig"); | ||||
| } | } | ||||
| $cscover = $this->projectRoot.DIRECTORY_SEPARATOR.$this->cscoverHintPath; | $cscover = $this->projectRoot.DIRECTORY_SEPARATOR.$this->cscoverHintPath; | ||||
| if (file_exists($cscover)) { | if (file_exists($cscover)) { | ||||
| $this->coverEngine = Filesystem::resolvePath($cscover); | $this->coverEngine = Filesystem::resolvePath($cscover); | ||||
| } else { | } else { | ||||
| throw new Exception( | throw new Exception( | ||||
| "Unable to locate cscover coverage runner ". | 'Unable to locate cscover coverage runner '. | ||||
| "(have you built yet?)"); | '(have you built yet?)'); | ||||
| } | } | ||||
| } | } | ||||
| /** | /** | ||||
| * Returns whether the specified assembly should be instrumented for | * Returns whether the specified assembly should be instrumented for | ||||
| * code coverage reporting. Checks the excluded file list and the | * code coverage reporting. Checks the excluded file list and the | ||||
| * matching regex if they are configured. | * matching regex if they are configured. | ||||
| Show All 27 Lines | final class CSharpToolsTestEngine extends XUnitTestEngine { | ||||
| protected function buildTestFuture($test_assembly) { | protected function buildTestFuture($test_assembly) { | ||||
| if ($this->getEnableCoverage() === false) { | if ($this->getEnableCoverage() === false) { | ||||
| return parent::buildTestFuture($test_assembly); | return parent::buildTestFuture($test_assembly); | ||||
| } | } | ||||
| // FIXME: Can't use TempFile here as xUnit doesn't like | // FIXME: Can't use TempFile here as xUnit doesn't like | ||||
| // UNIX-style full paths. It sees the leading / as the | // UNIX-style full paths. It sees the leading / as the | ||||
| // start of an option flag, even when quoted. | // start of an option flag, even when quoted. | ||||
| $xunit_temp = Filesystem::readRandomCharacters(10).".results.xml"; | $xunit_temp = Filesystem::readRandomCharacters(10).'.results.xml'; | ||||
| if (file_exists($xunit_temp)) { | if (file_exists($xunit_temp)) { | ||||
| unlink($xunit_temp); | unlink($xunit_temp); | ||||
| } | } | ||||
| $cover_temp = new TempFile(); | $cover_temp = new TempFile(); | ||||
| $cover_temp->setPreserveFile(true); | $cover_temp->setPreserveFile(true); | ||||
| $xunit_cmd = $this->runtimeEngine; | $xunit_cmd = $this->runtimeEngine; | ||||
| $xunit_args = null; | $xunit_args = null; | ||||
| if ($xunit_cmd === "") { | if ($xunit_cmd === '') { | ||||
| $xunit_cmd = $this->testEngine; | $xunit_cmd = $this->testEngine; | ||||
| $xunit_args = csprintf( | $xunit_args = csprintf( | ||||
| "%s /xml %s", | '%s /xml %s', | ||||
| $test_assembly, | $test_assembly, | ||||
| $xunit_temp); | $xunit_temp); | ||||
| } else { | } else { | ||||
| $xunit_args = csprintf( | $xunit_args = csprintf( | ||||
| "%s %s /xml %s", | '%s %s /xml %s', | ||||
| $this->testEngine, | $this->testEngine, | ||||
| $test_assembly, | $test_assembly, | ||||
| $xunit_temp); | $xunit_temp); | ||||
| } | } | ||||
| $assembly_dir = dirname($test_assembly); | $assembly_dir = dirname($test_assembly); | ||||
| $assemblies_to_instrument = array(); | $assemblies_to_instrument = array(); | ||||
| foreach (Filesystem::listDirectory($assembly_dir) as $file) { | foreach (Filesystem::listDirectory($assembly_dir) as $file) { | ||||
| if (substr($file, -4) == ".dll" || substr($file, -4) == ".exe") { | if (substr($file, -4) == '.dll' || substr($file, -4) == '.exe') { | ||||
| if ($this->assemblyShouldBeInstrumented($file)) { | if ($this->assemblyShouldBeInstrumented($file)) { | ||||
| $assemblies_to_instrument[] = $assembly_dir.DIRECTORY_SEPARATOR.$file; | $assemblies_to_instrument[] = $assembly_dir.DIRECTORY_SEPARATOR.$file; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (count($assemblies_to_instrument) === 0) { | if (count($assemblies_to_instrument) === 0) { | ||||
| return parent::buildTestFuture($test_assembly); | return parent::buildTestFuture($test_assembly); | ||||
| } | } | ||||
| $future = new ExecFuture( | $future = new ExecFuture( | ||||
| "%C -o %s -c %s -a %s -w %s %Ls", | '%C -o %s -c %s -a %s -w %s %Ls', | ||||
| trim($this->runtimeEngine." ".$this->coverEngine), | trim($this->runtimeEngine.' '.$this->coverEngine), | ||||
| $cover_temp, | $cover_temp, | ||||
| $xunit_cmd, | $xunit_cmd, | ||||
| $xunit_args, | $xunit_args, | ||||
| $assembly_dir, | $assembly_dir, | ||||
| $assemblies_to_instrument); | $assemblies_to_instrument); | ||||
| $future->setCWD(Filesystem::resolvePath($this->projectRoot)); | $future->setCWD(Filesystem::resolvePath($this->projectRoot)); | ||||
| return array( | return array( | ||||
| $future, | $future, | ||||
| ▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | final class CSharpToolsTestEngine extends XUnitTestEngine { | ||||
| * | * | ||||
| * @param array The array of XML tags to parse. | * @param array The array of XML tags to parse. | ||||
| * @return array A PHP array containing the data. | * @return array A PHP array containing the data. | ||||
| */ | */ | ||||
| private function processTags($tags) { | private function processTags($tags) { | ||||
| $results = array(); | $results = array(); | ||||
| foreach ($tags as $tag) { | foreach ($tags as $tag) { | ||||
| $results[] = array( | $results[] = array( | ||||
| "file" => $tag->getAttribute("file"), | 'file' => $tag->getAttribute('file'), | ||||
| "start" => $tag->getAttribute("start"), | 'start' => $tag->getAttribute('start'), | ||||
| "end" => $tag->getAttribute("end")); | 'end' => $tag->getAttribute('end')); | ||||
| } | } | ||||
| return $results; | return $results; | ||||
| } | } | ||||
| /** | /** | ||||
| * Reads the code coverage results from the cscover results file. | * Reads the code coverage results from the cscover results file. | ||||
| * | * | ||||
| * @param string The path to the code coverage file. | * @param string The path to the code coverage file. | ||||
| Show All 10 Lines | public function readCoverage($cover_file) { | ||||
| $modified = $this->getPaths(); | $modified = $this->getPaths(); | ||||
| $files = array(); | $files = array(); | ||||
| $reports = array(); | $reports = array(); | ||||
| $instrumented = array(); | $instrumented = array(); | ||||
| $executed = array(); | $executed = array(); | ||||
| $instrumented = $this->processTags( | $instrumented = $this->processTags( | ||||
| $coverage_dom->getElementsByTagName("instrumented")); | $coverage_dom->getElementsByTagName('instrumented')); | ||||
| $executed = $this->processTags( | $executed = $this->processTags( | ||||
| $coverage_dom->getElementsByTagName("executed")); | $coverage_dom->getElementsByTagName('executed')); | ||||
| foreach ($instrumented as $instrument) { | foreach ($instrumented as $instrument) { | ||||
| $absolute_file = $instrument["file"]; | $absolute_file = $instrument['file']; | ||||
| $relative_file = substr($absolute_file, strlen($this->projectRoot) + 1); | $relative_file = substr($absolute_file, strlen($this->projectRoot) + 1); | ||||
| if (!in_array($relative_file, $files)) { | if (!in_array($relative_file, $files)) { | ||||
| $files[] = $relative_file; | $files[] = $relative_file; | ||||
| } | } | ||||
| } | } | ||||
| foreach ($files as $file) { | foreach ($files as $file) { | ||||
| $absolute_file = Filesystem::resolvePath( | $absolute_file = Filesystem::resolvePath( | ||||
| $this->projectRoot.DIRECTORY_SEPARATOR.$file); | $this->projectRoot.DIRECTORY_SEPARATOR.$file); | ||||
| // get total line count in file | // get total line count in file | ||||
| $line_count = count(file($absolute_file)); | $line_count = count(file($absolute_file)); | ||||
| $coverage = array(); | $coverage = array(); | ||||
| for ($i = 0; $i < $line_count; $i++) { | for ($i = 0; $i < $line_count; $i++) { | ||||
| $coverage[$i] = 'N'; | $coverage[$i] = 'N'; | ||||
| } | } | ||||
| foreach ($instrumented as $instrument) { | foreach ($instrumented as $instrument) { | ||||
| if ($instrument["file"] !== $absolute_file) { | if ($instrument['file'] !== $absolute_file) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| for ( | for ( | ||||
| $i = $instrument["start"]; | $i = $instrument['start']; | ||||
| $i <= $instrument["end"]; | $i <= $instrument['end']; | ||||
| $i++) { | $i++) { | ||||
| $coverage[$i - 1] = 'U'; | $coverage[$i - 1] = 'U'; | ||||
| } | } | ||||
| } | } | ||||
| foreach ($executed as $execute) { | foreach ($executed as $execute) { | ||||
| if ($execute["file"] !== $absolute_file) { | if ($execute['file'] !== $absolute_file) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| for ( | for ( | ||||
| $i = $execute["start"]; | $i = $execute['start']; | ||||
| $i <= $execute["end"]; | $i <= $execute['end']; | ||||
| $i++) { | $i++) { | ||||
| $coverage[$i - 1] = 'C'; | $coverage[$i - 1] = 'C'; | ||||
| } | } | ||||
| } | } | ||||
| $reports[$file] = implode($coverage); | $reports[$file] = implode($coverage); | ||||
| } | } | ||||
| $this->addCachedResults($cover_file, $reports); | $this->addCachedResults($cover_file, $reports); | ||||
| return $reports; | return $reports; | ||||
| } | } | ||||
| } | } | ||||