Skip to content

Commit

Permalink
Refactoring the baseline handling.
Browse files Browse the repository at this point in the history
  • Loading branch information
floriankraemer committed Sep 24, 2024
1 parent c632384 commit 10c3a47
Show file tree
Hide file tree
Showing 8 changed files with 208 additions and 173 deletions.
54 changes: 54 additions & 0 deletions src/Business/Cognitive/BaselineService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

declare(strict_types=1);

namespace Phauthentic\CodeQualityMetrics\Business\Cognitive;

use RuntimeException;

/**
*
*/
class BaselineService
{
/**
* @param CognitiveMetricsCollection $metricsCollection
* @param array<string, array<string, mixed>> $baseline
*/
public function calculateDeltas(CognitiveMetricsCollection $metricsCollection, array $baseline): void
{
foreach ($baseline as $class => $data) {
foreach ($data['methods'] as $methodName => $methodData) {
$metrics = $metricsCollection->getClassWithMethod($class, $methodName);
if (!$metrics) {
continue;
}

$previousMetrics = CognitiveMetrics::fromArray($methodData);
$metrics->calculateDeltas($previousMetrics);
}
}
}


/**
* Loads the baseline file and returns the data as an array.
*
* @param string $baselineFile
* @return array<string, array<string, mixed>> $baseline
* @throws \JsonException
*/
public function loadBaseline(string $baselineFile): array
{
if (!file_exists($baselineFile)) {
throw new RuntimeException('Baseline file does not exist.');
}

$baseline = file_get_contents($baselineFile);
if ($baseline === false) {
throw new RuntimeException('Failed to read baseline file.');
}

return json_decode($baseline, true, 512, JSON_THROW_ON_ERROR);
}
}
84 changes: 55 additions & 29 deletions src/Business/Cognitive/CognitiveMetrics.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,23 @@
*/
class CognitiveMetrics implements JsonSerializable
{
private string $class = '';
private string $method = '';
/**
* @var array<int, string>
*/
private array $metrics = [
'lineCount',
'argCount',
'returnCount',
'variableCount',
'propertyCallCount',
'ifCount',
'ifNestingLevel',
'elseCount'
];

private string $class;
private string $method;

private int $lineCount = 0;
private int $argCount = 0;
private int $returnCount = 0;
Expand Down Expand Up @@ -49,25 +64,37 @@ public function __construct(array $metrics)
{
$this->assertArrayKeyIsPresent($metrics, 'class');

Check warning on line 65 in src/Business/Cognitive/CognitiveMetrics.php

View workflow job for this annotation

GitHub Actions / Coding Standard & Static Analysis

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ */ public function __construct(array $metrics) { - $this->assertArrayKeyIsPresent($metrics, 'class'); + $this->assertArrayKeyIsPresent($metrics, 'method'); $this->method = $metrics['method']; $this->class = $metrics['class'];

Check warning on line 65 in src/Business/Cognitive/CognitiveMetrics.php

View workflow job for this annotation

GitHub Actions / Coding Standard & Static Analysis

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ */ public function __construct(array $metrics) { - $this->assertArrayKeyIsPresent($metrics, 'class'); + $this->assertArrayKeyIsPresent($metrics, 'method'); $this->method = $metrics['method']; $this->class = $metrics['class'];
$this->assertArrayKeyIsPresent($metrics, 'method');

Check warning on line 66 in src/Business/Cognitive/CognitiveMetrics.php

View workflow job for this annotation

GitHub Actions / Coding Standard & Static Analysis

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ public function __construct(array $metrics) { $this->assertArrayKeyIsPresent($metrics, 'class'); - $this->assertArrayKeyIsPresent($metrics, 'method'); + $this->method = $metrics['method']; $this->class = $metrics['class']; $this->setRequiredMetricProperties($metrics);

Check warning on line 66 in src/Business/Cognitive/CognitiveMetrics.php

View workflow job for this annotation

GitHub Actions / Coding Standard & Static Analysis

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ public function __construct(array $metrics) { $this->assertArrayKeyIsPresent($metrics, 'class'); - $this->assertArrayKeyIsPresent($metrics, 'method'); + $this->method = $metrics['method']; $this->class = $metrics['class']; $this->setRequiredMetricProperties($metrics);
$this->assertArrayKeyIsPresent($metrics, 'lineCount');
$this->assertArrayKeyIsPresent($metrics, 'argCount');
$this->assertArrayKeyIsPresent($metrics, 'returnCount');
$this->assertArrayKeyIsPresent($metrics, 'variableCount');
$this->assertArrayKeyIsPresent($metrics, 'propertyCallCount');
$this->assertArrayKeyIsPresent($metrics, 'ifCount');
$this->assertArrayKeyIsPresent($metrics, 'ifNestingLevel');
$this->assertArrayKeyIsPresent($metrics, 'elseCount');

$this->class = $metrics['class'];
$this->method = $metrics['method'];
$this->lineCount = $metrics['lineCount'];
$this->argCount = $metrics['argCount'];
$this->returnCount = $metrics['returnCount'];
$this->variableCount = $metrics['variableCount'];
$this->propertyCallCount = $metrics['propertyCallCount'];
$this->ifCount = $metrics['ifCount'];
$this->ifNestingLevel = $metrics['ifNestingLevel'];
$this->elseCount = $metrics['elseCount'];
$this->class = $metrics['class'];

$this->setRequiredMetricProperties($metrics);
$this->setOptionalMetricProperties($metrics);

Check warning on line 71 in src/Business/Cognitive/CognitiveMetrics.php

View workflow job for this annotation

GitHub Actions / Coding Standard & Static Analysis

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ $this->method = $metrics['method']; $this->class = $metrics['class']; $this->setRequiredMetricProperties($metrics); - $this->setOptionalMetricProperties($metrics); + } /** * @param array<string, mixed> $metrics

Check warning on line 71 in src/Business/Cognitive/CognitiveMetrics.php

View workflow job for this annotation

GitHub Actions / Coding Standard & Static Analysis

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ $this->method = $metrics['method']; $this->class = $metrics['class']; $this->setRequiredMetricProperties($metrics); - $this->setOptionalMetricProperties($metrics); + } /** * @param array<string, mixed> $metrics
}

/**
* @param array<string, mixed> $metrics
* @return void
*/
private function setRequiredMetricProperties(array $metrics): void
{
foreach ($this->metrics as $metricName) {
$this->assertArrayKeyIsPresent($metrics, $metricName);

Check warning on line 81 in src/Business/Cognitive/CognitiveMetrics.php

View workflow job for this annotation

GitHub Actions / Coding Standard & Static Analysis

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ private function setRequiredMetricProperties(array $metrics): void { foreach ($this->metrics as $metricName) { - $this->assertArrayKeyIsPresent($metrics, $metricName); + $this->{$metricName} = $metrics[$metricName]; } }

Check warning on line 81 in src/Business/Cognitive/CognitiveMetrics.php

View workflow job for this annotation

GitHub Actions / Coding Standard & Static Analysis

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ private function setRequiredMetricProperties(array $metrics): void { foreach ($this->metrics as $metricName) { - $this->assertArrayKeyIsPresent($metrics, $metricName); + $this->{$metricName} = $metrics[$metricName]; } }
$this->$metricName = $metrics[$metricName];
}
}

/**
* @param array<string, mixed> $metrics
* @return void
*/
private function setOptionalMetricProperties(array $metrics): void
{
foreach ($this->metrics as $metricName) {

Check warning on line 92 in src/Business/Cognitive/CognitiveMetrics.php

View workflow job for this annotation

GitHub Actions / Coding Standard & Static Analysis

Escaped Mutant for Mutator "Foreach_": @@ @@ */ private function setOptionalMetricProperties(array $metrics): void { - foreach ($this->metrics as $metricName) { + foreach ([] as $metricName) { $property = $metricName . 'Weight'; if (array_key_exists($property, $metrics)) { $this->{$property} = $metrics[$property];

Check warning on line 92 in src/Business/Cognitive/CognitiveMetrics.php

View workflow job for this annotation

GitHub Actions / Coding Standard & Static Analysis

Escaped Mutant for Mutator "Foreach_": @@ @@ */ private function setOptionalMetricProperties(array $metrics): void { - foreach ($this->metrics as $metricName) { + foreach ([] as $metricName) { $property = $metricName . 'Weight'; if (array_key_exists($property, $metrics)) { $this->{$property} = $metrics[$property];
$property = $metricName . 'Weight';

Check warning on line 93 in src/Business/Cognitive/CognitiveMetrics.php

View workflow job for this annotation

GitHub Actions / Coding Standard & Static Analysis

Escaped Mutant for Mutator "Concat": @@ @@ private function setOptionalMetricProperties(array $metrics): void { foreach ($this->metrics as $metricName) { - $property = $metricName . 'Weight'; + $property = 'Weight' . $metricName; if (array_key_exists($property, $metrics)) { $this->{$property} = $metrics[$property]; }

Check warning on line 93 in src/Business/Cognitive/CognitiveMetrics.php

View workflow job for this annotation

GitHub Actions / Coding Standard & Static Analysis

Escaped Mutant for Mutator "ConcatOperandRemoval": @@ @@ private function setOptionalMetricProperties(array $metrics): void { foreach ($this->metrics as $metricName) { - $property = $metricName . 'Weight'; + $property = 'Weight'; if (array_key_exists($property, $metrics)) { $this->{$property} = $metrics[$property]; }

Check warning on line 93 in src/Business/Cognitive/CognitiveMetrics.php

View workflow job for this annotation

GitHub Actions / Coding Standard & Static Analysis

Escaped Mutant for Mutator "ConcatOperandRemoval": @@ @@ private function setOptionalMetricProperties(array $metrics): void { foreach ($this->metrics as $metricName) { - $property = $metricName . 'Weight'; + $property = $metricName; if (array_key_exists($property, $metrics)) { $this->{$property} = $metrics[$property]; }

Check warning on line 93 in src/Business/Cognitive/CognitiveMetrics.php

View workflow job for this annotation

GitHub Actions / Coding Standard & Static Analysis

Escaped Mutant for Mutator "Concat": @@ @@ private function setOptionalMetricProperties(array $metrics): void { foreach ($this->metrics as $metricName) { - $property = $metricName . 'Weight'; + $property = 'Weight' . $metricName; if (array_key_exists($property, $metrics)) { $this->{$property} = $metrics[$property]; }

Check warning on line 93 in src/Business/Cognitive/CognitiveMetrics.php

View workflow job for this annotation

GitHub Actions / Coding Standard & Static Analysis

Escaped Mutant for Mutator "ConcatOperandRemoval": @@ @@ private function setOptionalMetricProperties(array $metrics): void { foreach ($this->metrics as $metricName) { - $property = $metricName . 'Weight'; + $property = 'Weight'; if (array_key_exists($property, $metrics)) { $this->{$property} = $metrics[$property]; }

Check warning on line 93 in src/Business/Cognitive/CognitiveMetrics.php

View workflow job for this annotation

GitHub Actions / Coding Standard & Static Analysis

Escaped Mutant for Mutator "ConcatOperandRemoval": @@ @@ private function setOptionalMetricProperties(array $metrics): void { foreach ($this->metrics as $metricName) { - $property = $metricName . 'Weight'; + $property = $metricName; if (array_key_exists($property, $metrics)) { $this->{$property} = $metrics[$property]; }
if (array_key_exists($property, $metrics)) {
$this->$property = $metrics[$property];
}
}
}

private function assertSame(self $other): void
Expand All @@ -93,17 +120,16 @@ public function calculateDeltas(self $other): void
{
$this->assertSame($other);

Check warning on line 121 in src/Business/Cognitive/CognitiveMetrics.php

View workflow job for this annotation

GitHub Actions / Coding Standard & Static Analysis

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ */ public function calculateDeltas(self $other): void { - $this->assertSame($other); + $this->lineCountWeightDelta = new Delta($other->getLineCountWeight(), $this->lineCountWeight); $this->argCountWeightDelta = new Delta($other->getArgCountWeight(), $this->argCountWeight); $this->returnCountWeightDelta = new Delta($other->getReturnCountWeight(), $this->returnCountWeight);

Check warning on line 121 in src/Business/Cognitive/CognitiveMetrics.php

View workflow job for this annotation

GitHub Actions / Coding Standard & Static Analysis

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ */ public function calculateDeltas(self $other): void { - $this->assertSame($other); + $this->lineCountWeightDelta = new Delta($other->getLineCountWeight(), $this->lineCountWeight); $this->argCountWeightDelta = new Delta($other->getArgCountWeight(), $this->argCountWeight); $this->returnCountWeightDelta = new Delta($other->getReturnCountWeight(), $this->returnCountWeight);

$this->lineCountWeightDelta = new Delta($this->lineCountWeight, $other->getLineCountWeight());
$this->argCountWeightDelta = new Delta($this->argCountWeight, $other->getArgCountWeight());
$this->returnCountWeightDelta = new Delta($this->returnCountWeight, $other->getReturnCountWeight());
$this->variableCountWeightDelta = new Delta($this->variableCountWeight, $other->getVariableCountWeight());
$this->propertyCallCountWeightDelta = new Delta($this->propertyCallCountWeight, $other->getPropertyCallCountWeight());
$this->ifCountWeightDelta = new Delta($this->ifCountWeight, $other->getIfCountWeight());
$this->ifNestingLevelWeightDelta = new Delta($this->ifNestingLevelWeight, $other->getIfNestingLevelWeight());
$this->elseCountWeightDelta = new Delta($this->elseCountWeight, $other->getElseCountWeight());
$this->lineCountWeightDelta = new Delta($other->getLineCountWeight(), $this->lineCountWeight);
$this->argCountWeightDelta = new Delta($other->getArgCountWeight(), $this->argCountWeight);
$this->returnCountWeightDelta = new Delta($other->getReturnCountWeight(), $this->returnCountWeight);
$this->variableCountWeightDelta = new Delta($other->getVariableCountWeight(), $this->variableCountWeight);
$this->propertyCallCountWeightDelta = new Delta($other->getPropertyCallCountWeight(), $this->propertyCallCountWeight);
$this->ifCountWeightDelta = new Delta($other->getIfCountWeight(), $this->ifCountWeight);
$this->ifNestingLevelWeightDelta = new Delta($other->getIfNestingLevelWeight(), $this->ifNestingLevelWeight);
$this->elseCountWeightDelta = new Delta($other->getElseCountWeight(), $this->elseCountWeight);
}


/**
* @param array<string, mixed> $metrics
* @return self
Expand Down
9 changes: 7 additions & 2 deletions src/Business/Cognitive/Delta.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ public function __construct(float $before, float $after)
{
if ($before < $after) {
$this->hasIncreased = true;
$this->difference = $after - $before; // Positive difference for increase
$this->difference = $after - $before;
return;
}

$this->hasIncreased = false;
$this->difference = $after - $before; // Negative difference for decrease or zero
$this->difference = $after - $before;
}

public function getValue(): float
Expand All @@ -38,4 +38,9 @@ public function __toString(): string
{
return (string)$this->difference;
}

public function hasNotChanged(): bool
{
return $this->difference === 0.0;
}
}
48 changes: 24 additions & 24 deletions src/Business/Cognitive/Exporter/JsonExporter.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@
namespace Phauthentic\CodeQualityMetrics\Business\Cognitive\Exporter;

use Phauthentic\CodeQualityMetrics\Business\Cognitive\CognitiveMetricsCollection;
use RuntimeException;

/**
*
*/
class JsonExporter implements DataExporterInterface
{
/**
* @throws \JsonException
*/
public function export(CognitiveMetricsCollection $metricsCollection, string $filename): void
{
$jsonData = [];
Expand All @@ -19,38 +23,34 @@ public function export(CognitiveMetricsCollection $metricsCollection, string $fi

foreach ($groupedByClass as $class => $methods) {
foreach ($methods as $metrics) {
$jsonData[] = [
$jsonData[$class]['methods'][$metrics->getMethod()] = [
'class' => $metrics->getClass(),
'methods' => [
$metrics->getMethod() => [
'name' => $metrics->getMethod(),
'lineCount' => $metrics->getLineCount(),
'lineCountWeight' => $metrics->getLineCountWeight(),
'argCount' => $metrics->getArgCount(),
'argCountWeight' => $metrics->getArgCountWeight(),
'returnCount' => $metrics->getReturnCount(),
'returnCountWeight' => $metrics->getReturnCountWeight(),
'variableCount' => $metrics->getVariableCount(),
'variableCountWeight' => $metrics->getVariableCountWeight(),
'propertyCallCount' => $metrics->getPropertyCallCount(),
'propertyCallCountWeight' => $metrics->getPropertyCallCountWeight(),
'ifCount' => $metrics->getIfCount(),
'ifCountWeight' => $metrics->getIfCountWeight(),
'ifNestingLevel' => $metrics->getIfNestingLevel(),
'ifNestingLevelWeight' => $metrics->getIfNestingLevelWeight(),
'elseCount' => $metrics->getElseCount(),
'elseCountWeight' => $metrics->getElseCountWeight(),
'score' => $metrics->getScore()
]
]
'method' => $metrics->getMethod(),
'lineCount' => $metrics->getLineCount(),
'lineCountWeight' => $metrics->getLineCountWeight(),
'argCount' => $metrics->getArgCount(),
'argCountWeight' => $metrics->getArgCountWeight(),
'returnCount' => $metrics->getReturnCount(),
'returnCountWeight' => $metrics->getReturnCountWeight(),
'variableCount' => $metrics->getVariableCount(),
'variableCountWeight' => $metrics->getVariableCountWeight(),
'propertyCallCount' => $metrics->getPropertyCallCount(),
'propertyCallCountWeight' => $metrics->getPropertyCallCountWeight(),
'ifCount' => $metrics->getIfCount(),
'ifCountWeight' => $metrics->getIfCountWeight(),
'ifNestingLevel' => $metrics->getIfNestingLevel(),
'ifNestingLevelWeight' => $metrics->getIfNestingLevelWeight(),
'elseCount' => $metrics->getElseCount(),
'elseCountWeight' => $metrics->getElseCountWeight(),
'score' => $metrics->getScore()
];
}
}

$jsonData = json_encode($jsonData, JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR);

if (file_put_contents($filename, $jsonData) === false) {
throw new \RuntimeException("Unable to write to file: $filename");
throw new RuntimeException("Unable to write to file: $filename");
}
}
}
42 changes: 11 additions & 31 deletions src/Command/CognitiveMetricsCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Phauthentic\CodeQualityMetrics\Command;

use Exception;
use Phauthentic\CodeQualityMetrics\Business\Cognitive\BaselineService;
use Phauthentic\CodeQualityMetrics\Business\Cognitive\CognitiveMetricsCollection;
use Phauthentic\CodeQualityMetrics\Business\MetricsFacade;
use Phauthentic\CodeQualityMetrics\Command\Presentation\CognitiveMetricTextRenderer;
Expand Down Expand Up @@ -34,6 +35,7 @@ class CognitiveMetricsCommand extends Command

private MetricsFacade $metricsFacade;
private CognitiveMetricTextRenderer $metricTextRenderer;
private BaselineService $baselineService;

/**
* Constructor to initialize dependencies.
Expand All @@ -43,6 +45,7 @@ public function __construct()
parent::__construct();
$this->metricsFacade = new MetricsFacade();
$this->metricTextRenderer = new CognitiveMetricTextRenderer();
$this->baselineService = new BaselineService();
}

/**
Expand Down Expand Up @@ -76,19 +79,19 @@ protected function execute(InputInterface $input, OutputInterface $output): int
return Command::FAILURE;
}

// Load baseline if the option is provided.
$baseline = $this->handleBaseLine($input);

// Generate metrics for the provided path.
$metricsCollection = $this->metricsFacade->getCognitiveMetrics($path);

// Load baseline if the option is provided.
$this->handleBaseLine($input, $metricsCollection);

// Handle different export options.
if (!$this->handleExportOptions($input, $output, $metricsCollection)) {
return Command::FAILURE;
}

// Render the metrics to the console.
$this->metricTextRenderer->render($metricsCollection, $baseline, $output);
$this->metricTextRenderer->render($metricsCollection, [], $output);

return Command::SUCCESS;
}
Expand All @@ -97,39 +100,16 @@ protected function execute(InputInterface $input, OutputInterface $output): int
* Handles the baseline option and loads the baseline file if provided.
*
* @param InputInterface $input
* @return array<int, array<string, mixed>>
* @param CognitiveMetricsCollection $metricsCollection
* @throws Exception
*/
private function handleBaseLine(InputInterface $input): array
private function handleBaseLine(InputInterface $input, CognitiveMetricsCollection $metricsCollection): void
{
$baseline = [];
$baselineFile = $input->getOption(self::OPTION_BASELINE);
if ($baselineFile) {
$baseline = $this->loadBaseline($baselineFile);
}

return $baseline;
}

/**
* Loads the baseline file and returns the data as an array.
*
* @param string $baselineFile
* @return array<int, array<string, mixed>> $baseline
* @throws \JsonException
*/
private function loadBaseline(string $baselineFile): array
{
if (!file_exists($baselineFile)) {
throw new Exception('Baseline file does not exist.');
}

$baseline = file_get_contents($baselineFile);
if ($baseline === false) {
throw new Exception('Failed to read baseline file.');
$baseline = $this->baselineService->loadBaseline($baselineFile);
$this->baselineService->calculateDeltas($metricsCollection, $baseline);
}

return json_decode($baseline, true, 512, JSON_THROW_ON_ERROR);
}

/**
Expand Down
Loading

0 comments on commit 10c3a47

Please sign in to comment.