Skip to content

Commit

Permalink
working phpcs sensor
Browse files Browse the repository at this point in the history
  • Loading branch information
julianseeger committed Jul 5, 2014
1 parent 76d9b9a commit 0ecf359
Show file tree
Hide file tree
Showing 5 changed files with 251 additions and 9 deletions.
6 changes: 6 additions & 0 deletions core/src/Interactor/AddMaterialInteractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Metrics\Core\Entity\MaterialType;
use Metrics\Core\Interactor\Sensor\Clover\CloverSensor;
use Metrics\Core\Interactor\Sensor\Phpcs\PhpcsSensor;
use Metrics\Core\Interactor\Sensor\Sensor;
use Metrics\Core\Repository\FileRepository;
use Metrics\Core\Repository\FileVersionRepository;
Expand Down Expand Up @@ -63,6 +64,11 @@ public function execute($projectName, $versionLabel, $materialTypeName, $materia
$this->fileRepository,
$this->fileVersionRepository,
$this->metricsRepository
),
new PhpcsSensor(
$this->fileRepository,
$this->fileVersionRepository,
$this->metricsRepository
)
];

Expand Down
18 changes: 18 additions & 0 deletions core/src/Interactor/Sensor/AbstractSensor.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace Metrics\Core\Interactor\Sensor;

use Metrics\Core\Entity\DirectoryVersion;

abstract class AbstractSensor implements Sensor
{
/**
Expand All @@ -28,4 +30,20 @@ public function getPrefixByPathArray(array $paths)

return join('/', $prefix);
}

/**
* @param DirectoryVersion $dir
*/
protected function attachDirectoryMetrics(DirectoryVersion $dir)
{
foreach ($dir->getFiles() as $file) {
if ($file instanceof DirectoryVersion) {
$this->attachDirectoryMetrics($file);
}
}

$this->calculateDirectoryMetrics($dir);
}

abstract protected function calculateDirectoryMetrics(DirectoryVersion $dir);
}
10 changes: 1 addition & 9 deletions core/src/Interactor/Sensor/Clover/CloverSensor.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,16 +126,8 @@ private function attachMetrics($fileVersion, $cloverFile)
}
}

/**
* @param DirectoryVersion $dir
*/
private function attachDirectoryMetrics(DirectoryVersion $dir)
protected function calculateDirectoryMetrics(DirectoryVersion $dir)
{
foreach ($dir->getFiles() as $file) {
if ($file instanceof DirectoryVersion) {
$this->attachDirectoryMetrics($file);
}
}
$lineCoverageMetric = $this->metricRepository->getMetric(Metric::LINE_COVERAGE);
$statementsMetric = $this->metricRepository->getMetric('statements');
$coveredstatementsMetric = $this->metricRepository->getMetric('coveredstatements');
Expand Down
105 changes: 105 additions & 0 deletions core/src/Interactor/Sensor/Phpcs/PhpcsSensor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<?php

namespace Metrics\Core\Interactor\Sensor\Phpcs;

use Metrics\Core\Entity\DirectoryVersion;
use Metrics\Core\Entity\MaterialType;
use Metrics\Core\Entity\Project;
use Metrics\Core\Entity\Version;
use Metrics\Core\Interactor\Sensor\AbstractSensor;
use Metrics\Core\Interactor\Sensor\Phpcs\Dto\PhpcsReport;
use Metrics\Core\Interactor\Sensor\Sensor;
use Metrics\Core\Repository\FileRepository;
use Metrics\Core\Repository\FileVersionRepository;
use Metrics\Core\Repository\MetricRepository;

class PhpcsSensor extends AbstractSensor implements Sensor
{
const VIOLATIONS_METRIC_NAME = 'PHPCS Violations';
/**
* @var FileRepository
*/
private $fileRepository;

/**
* @var FileVersionRepository
*/
private $fileVersionRepository;

/**
* @var MetricRepository
*/
private $metricRepository;

public function __construct(
FileRepository $fileRepository,
FileVersionRepository $fileVersionRepository,
MetricRepository $metricRepository
) {
$this->fileRepository = $fileRepository;
$this->fileVersionRepository = $fileVersionRepository;
$this->metricRepository = $metricRepository;
}

/**
* @param string $material
* @param Project $project
* @param Version $version
* @return mixed
*/
public function execute($material, Project $project, Version $version)
{
$this->registerMetrics();

$report = PhpcsReport::parse(simplexml_load_string($material));

$prefix = $this->detectPrefix($report);
$this->addFiles($report, $prefix, $version);

$this->attachDirectoryMetrics($version->getRoot());
}

/**
* @param MaterialType $materialType
* @return bool
*/
public function supportsMaterialType(MaterialType $materialType)
{
return $materialType->getName() === 'phpcs';
}

private function registerMetrics()
{
$metric = $this->metricRepository->getMetric(self::VIOLATIONS_METRIC_NAME);
$metric->setInternal(false);
$metric->setPercentaged(false);
$this->metricRepository->save($metric);
}

private function detectPrefix(PhpcsReport $report)
{
$paths = [];
foreach ($report->files as $file) {
$paths[] = $file->name;
}
return $this->getPrefixByPathArray($paths);
}

protected function calculateDirectoryMetrics(DirectoryVersion $dir)
{
$violationsMetric = $this->metricRepository->getMetric(self::VIOLATIONS_METRIC_NAME);
$value = $dir->getMetricValue($violationsMetric, true);
$dir->addMetricValue($violationsMetric, $value);
}

private function addFiles(PhpcsReport $report, $prefix, Version $version)
{
$violationsMetric = $this->metricRepository->getMetric(self::VIOLATIONS_METRIC_NAME);
foreach ($report->files as $file) {
$relativePath = str_replace($prefix, '', $file->name);

$fileVersion = $this->fileVersionRepository->createFile($relativePath, $version);
$fileVersion->addMetricValue($violationsMetric, $file->warningCount + $file->errorCount);
}
}
}
121 changes: 121 additions & 0 deletions core/tests/Interactor/Sensor/Phpcs/PhpcsSensorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
<?php

namespace Interactor\Sensor\Phpcs;

use Metrics\Core\Entity\DirectoryVersion;
use Metrics\Core\Entity\MaterialType;
use Metrics\Core\Entity\Project;
use Metrics\Core\Entity\Version;
use Metrics\Core\Interactor\Sensor\Phpcs\PhpcsSensor;
use Metrics\Core\Repository\FileRepository;
use Metrics\Core\Repository\FileRepositoryMock;
use Metrics\Core\Repository\FileVersionRepositoryMock;
use Metrics\Core\Repository\MetricRepository;
use Metrics\Core\Repository\FileVersionRepository;
use Metrics\Core\Repository\MetricRepositoryMock;

class PhpcsSensorTest extends \PHPUnit_Framework_TestCase
{
private $fixture = <<<'FIXTURE'
<?xml version="1.0" encoding="UTF-8"?>
<phpcs version="1.5.3">
<file name="/home/julian/PhpstormProjects/ASD/migrations/deltas/Version20140515175057.php"
errors="8" warnings="1">
<error line="15" column="16" source="PSR2.Methods.FunctionCallSignature.ContentAfterOpenBracket"
severity="5">Opening parenthesis of a multi-line function call must be the last content on the line</error>
<error line="366" column="10" source="PSR2.Methods.FunctionCallSignature.CloseBracketLine"
severity="5">Closing parenthesis of a multi-line function call must be on a line by itself</error>
<error line="368" column="16" source="PSR2.Methods.FunctionCallSignature.ContentAfterOpenBracket"
severity="5">Opening parenthesis of a multi-line function call must be the last content on the line</error>
<error line="376" column="10" source="PSR2.Methods.FunctionCallSignature.CloseBracketLine"
severity="5">Closing parenthesis of a multi-line function call must be on a line by itself</error>
<error line="378" column="16" source="PSR2.Methods.FunctionCallSignature.ContentAfterOpenBracket"
severity="5">Opening parenthesis of a multi-line function call must be the last content on the line</error>
<error line="397" column="10" source="PSR2.Methods.FunctionCallSignature.CloseBracketLine"
severity="5">Closing parenthesis of a multi-line function call must be on a line by itself</error>
<error line="399" column="16" source="PSR2.Methods.FunctionCallSignature.ContentAfterOpenBracket"
severity="5">Opening parenthesis of a multi-line function call must be the last content on the line</error>
<warning line="400" column="1" source="Generic.Files.LineLength.TooLong"
severity="5">Line exceeds 120 characters; contains 262 characters</warning>
<error line="401" column="10" source="PSR2.Methods.FunctionCallSignature.CloseBracketLine"
severity="5">Closing parenthesis of a multi-line function call must be on a line by itself</error>
</file>
<file name="/home/julian/PhpstormProjects/ASD/something/Version20140613103354.php"
errors="4" warnings="0">
<error line="15" column="16" source="PSR2.Methods.FunctionCallSignature.ContentAfterOpenBracket"
severity="5">Opening parenthesis of a multi-line function call must be the last content on the line</error>
<error line="18" column="10" source="PSR2.Methods.FunctionCallSignature.CloseBracketLine"
severity="5">Closing parenthesis of a multi-line function call must be on a line by itself</error>
<error line="19" column="16" source="PSR2.Methods.FunctionCallSignature.ContentAfterOpenBracket"
severity="5">Opening parenthesis of a multi-line function call must be the last content on the line</error>
<error line="22" column="10" source="PSR2.Methods.FunctionCallSignature.CloseBracketLine"
severity="5">Closing parenthesis of a multi-line function call must be on a line by itself</error>
</file>
</phpcs>
FIXTURE;

/**
* @var Project
*/
private $project;

/**
* @var Version
*/
private $version;

/**
* @var MetricRepository
*/
private $metricsRepository;
/**
* @var FileRepository
*/
private $fileRepository;
/**
* @var FileVersionRepository
*/
private $fileVersionRepository;

protected function setUp()
{
parent::setUp();
$this->metricsRepository = new MetricRepositoryMock();
$this->fileRepository = new FileRepositoryMock();
$this->fileVersionRepository = new FileVersionRepositoryMock();
$this->project = new Project("test");
$this->version = new Version("1", $this->project);
}

public function testMetricIsRegistered()
{
$sensor = new PhpcsSensor($this->fileRepository, $this->fileVersionRepository, $this->metricsRepository);
$sensor->execute($this->fixture, $this->project, $this->version);

$this->assertGreaterThan(0, count($this->metricsRepository->getMetrics()));
$metric = $this->metricsRepository->getMetric(PhpcsSensor::VIOLATIONS_METRIC_NAME);
$this->assertFalse($metric->isInternal());
$this->assertFalse($metric->isPercentaged());
}

public function testSupportsOnlyPhpcs()
{
$sensor = new PhpcsSensor($this->fileRepository, $this->fileVersionRepository, $this->metricsRepository);
$this->assertTrue($sensor->supportsMaterialType(new MaterialType('phpcs')));
$this->assertFalse($sensor->supportsMaterialType(new MaterialType('clover')));
}

public function testAttachesIssueCountToFilesAndFolders()
{
$sensor = new PhpcsSensor($this->fileRepository, $this->fileVersionRepository, $this->metricsRepository);
$sensor->execute($this->fixture, $this->project, $this->version);

$root = $this->version->getRoot();
$this->assertNotNull($root);
$this->assertTrue($root->hasFile('migrations'));
/** @var DirectoryVersion $directory */
$directory = $root->getFile('migrations');
$violationsMetric = $this->metricsRepository->getMetric(PhpcsSensor::VIOLATIONS_METRIC_NAME);
$this->assertEquals(9, $directory->getMetricValue($violationsMetric));
}
}

0 comments on commit 0ecf359

Please sign in to comment.