Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,14 @@ parameters:
# phpstan has hard time to check whenever we are using PHPUnit 10 or PHPUnit 9
-
message: '#Class SebastianBergmann\\CodeCoverage\\Report\\Text constructor invoked with 4 parameters, 1-3 required\.#'
count: 1
path: ./src/CodeCoverageExtension.php
-
message: "#^Parameter \\#1 \\$thresholds of class SebastianBergmann\\\\CodeCoverage\\\\Report\\\\Text constructor expects SebastianBergmann\\\\CodeCoverage\\\\Report\\\\Thresholds, int given\\.$#"
count: 1
path: src/CodeCoverageExtension.php

-
message: "#^Parameter \\#2 \\$showUncoveredFiles of class SebastianBergmann\\\\CodeCoverage\\\\Report\\\\Text constructor expects bool, int given\\.$#"
count: 1
path: src/CodeCoverageExtension.php
16 changes: 11 additions & 5 deletions spec/CodeCoverageExtensionSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Exception;
use FriendsOfPhpSpec\PhpSpec\CodeCoverage\CodeCoverageExtension;
use FriendsOfPhpSpec\PhpSpec\CodeCoverage\CodeCoverageOptions;
use PhpSpec\ObjectBehavior;
use PhpSpec\ServiceContainer\IndexedServiceContainer;

Expand All @@ -25,9 +26,10 @@ public function it_should_allow_to_set_show_only_summary_option(): void
$container->setParam('code_coverage', ['show_only_summary' => true]);
$this->load($container);

/** @var CodeCoverageOptions $options */
$options = $container->get('code_coverage.options');

if (true !== $options['show_only_summary']) {
if (true !== $options->showOnlySummary()) {
throw new Exception('show_only_summary was not set');
}
}
Expand All @@ -37,9 +39,10 @@ public function it_should_not_use_show_only_summary_option_by_default(): void
$container = new IndexedServiceContainer();
$this->load($container, []);

/** @var CodeCoverageOptions $options */
$options = $container->get('code_coverage.options');

if (false !== $options['show_only_summary']) {
if (false !== $options->showOnlySummary()) {
throw new Exception('show_only_summary should be `false` by default');
}
}
Expand All @@ -50,9 +53,10 @@ public function it_should_transform_format_into_array(): void
$container->setParam('code_coverage', ['format' => 'html']);
$this->load($container);

/** @var CodeCoverageOptions $options */
$options = $container->get('code_coverage.options');

if ($options['format'] !== ['html']) {
if ($options->getFormats() !== ['html']) {
throw new Exception('Default format is not transformed to an array');
}
}
Expand All @@ -62,9 +66,10 @@ public function it_should_use_html_format_by_default(): void
$container = new IndexedServiceContainer();
$this->load($container, []);

/** @var CodeCoverageOptions $options */
$options = $container->get('code_coverage.options');

if ($options['format'] !== ['html']) {
if ($options->getFormats() !== ['html']) {
throw new Exception('Default format is not html');
}
}
Expand All @@ -75,9 +80,10 @@ public function it_should_use_singular_output(): void
$container->setParam('code_coverage', ['output' => 'test', 'format' => 'foo']);
$this->load($container);

/** @var CodeCoverageOptions $options */
$options = $container->get('code_coverage.options');

if (['foo' => 'test'] !== $options['output']) {
if (['foo' => 'test'] !== $options->getOutputPaths()) {
throw new Exception('Default format is not singular output');
}
}
Expand Down
48 changes: 25 additions & 23 deletions src/CodeCoverageExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,62 +100,56 @@ public function load(ServiceContainer $container, array $params = []): void
$options['show_only_summary'] = false;
}

return $options;
return new CodeCoverageOptions($options);
});

$container->define('code_coverage.reports', static function (ServiceContainer $container) {
/** @var array<string, mixed> $options */
$options = $container->get('code_coverage.options');
/** @var CodeCoverageOptions $optionsWrapper */
$optionsWrapper = $container->get('code_coverage.options');
$options = $optionsWrapper->getOptions();

$reports = [];

foreach ($options['format'] as $format) {
foreach ($optionsWrapper->getFormats() as $format) {
switch ($format) {
case 'clover':
$reports['clover'] = new Report\Clover();

break;
case 'php':
$reports['php'] = new Report\PHP();

break;
case 'text':
$reports['text'] = version_compare(Version::id(), '10.0.0', '>=') && class_exists(Thresholds::class)
? new Report\Text(
Thresholds::from($options['lower_upper_bound'], $options['high_lower_bound']),
$options['show_uncovered_files'],
$options['show_only_summary']
Thresholds::from($optionsWrapper->getLowerUpperBound(), $optionsWrapper->getHighLowerBound()),
$optionsWrapper->showUncoveredFiles(), // @phpstan-ignore-line Version 10.0.0+ uses Thresholds
$optionsWrapper->showOnlySummary()
)
: new Report\Text(
$options['lower_upper_bound'],
$options['high_lower_bound'],
$options['show_uncovered_files'],
$options['show_only_summary']
$optionsWrapper->getLowerUpperBound(),
$optionsWrapper->getHighLowerBound(),
$optionsWrapper->showUncoveredFiles(),
$optionsWrapper->showOnlySummary()
);

break;
case 'xml':
$reports['xml'] = new Report\Xml\Facade(Version::id());

break;
case 'crap4j':
$reports['crap4j'] = new Report\Crap4j();

break;
case 'html':
$reports['html'] = new Report\Html\Facade();

break;
case 'cobertura':
$reports['cobertura'] = new Report\Cobertura();

break;
}
}

$container->setParam('code_coverage', $options);

return $reports;
return new CodeCoverageReports($reports);
});

$container->define('event_dispatcher.listeners.code_coverage', static function (ServiceContainer $container) {
Expand All @@ -169,11 +163,19 @@ public function load(ServiceContainer $container, array $params = []): void
/** @var CodeCoverage $codeCoverage */
$codeCoverage = $container->get('code_coverage');

/** @var array<string, object> $codeCoverageReports */
$codeCoverageReports = $container->get('code_coverage.reports');
/** @var CodeCoverageReports $codeCoverageReportsWrapper */
$codeCoverageReportsWrapper = $container->get('code_coverage.reports');

/** @var CodeCoverageOptions $optionsWrapper */
$optionsWrapper = $container->get('code_coverage.options');

$listener = new CodeCoverageListener($consoleIO, $codeCoverage, $codeCoverageReports, $skipCoverage);
$listener->setOptions($container->getParam('code_coverage', []));
$listener = new CodeCoverageListener(
$consoleIO,
$codeCoverage,
$codeCoverageReportsWrapper->getReports(),
$skipCoverage
);
$listener->setOptions($optionsWrapper->getOptions());

return $listener;
}, ['event_dispatcher.listeners']);
Expand Down
105 changes: 105 additions & 0 deletions src/CodeCoverageOptions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<?php

/**
* This file is part of the friends-of-phpspec/phpspec-code-coverage package.
*
* @author ek9 <dev@ek9.co>
* @license MIT
*
* For the full copyright and license information, please see the LICENSE file
* that was distributed with this source code.
*/

declare(strict_types=1);

namespace FriendsOfPhpSpec\PhpSpec\CodeCoverage;

class CodeCoverageOptions
{
/**
* @var array<string, mixed>
*/
private $options;

/**
* @param array<string, mixed> $options
*/
public function __construct(array $options)
{
$this->options = $options;
}

/**
* @return array<string, mixed>
*/
public function getOptions(): array
{
return $this->options;
}

/**
* @return mixed
*/
public function get(string $key)
{
return $this->options[$key] ?? null;
}

/**
* @param mixed $default
*
* @return mixed
*/
public function getWithDefault(string $key, $default)
{
return $this->options[$key] ?? $default;
}

/**
* @return array<string>
*/
public function getFormats(): array
{
return $this->options['format'] ?? ['html'];
}

/**
* @return array<string, string>
*/
public function getOutputPaths(): array
{
return $this->options['output'] ?? [];
}

/**
* @return bool
*/
public function showUncoveredFiles(): bool
{
return $this->options['show_uncovered_files'] ?? true;
}

/**
* @return int
*/
public function getLowerUpperBound(): int
{
return $this->options['lower_upper_bound'] ?? 35;
}

/**
* @return int
*/
public function getHighLowerBound(): int
{
return $this->options['high_lower_bound'] ?? 70;
}

/**
* @return bool
*/
public function showOnlySummary(): bool
{
return $this->options['show_only_summary'] ?? false;
}
}
62 changes: 62 additions & 0 deletions src/CodeCoverageReports.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

/**
* This file is part of the friends-of-phpspec/phpspec-code-coverage package.
*
* @author ek9 <dev@ek9.co>
* @license MIT
*
* For the full copyright and license information, please see the LICENSE file
* that was distributed with this source code.
*/

declare(strict_types=1);

namespace FriendsOfPhpSpec\PhpSpec\CodeCoverage;

class CodeCoverageReports
{
/**
* @var array<string, object>
*/
private $reports;

/**
* @param array<string, object> $reports
*/
public function __construct(array $reports)
{
$this->reports = $reports;
}

/**
* @return array<string, object>
*/
public function getReports(): array
{
return $this->reports;
}

public function getReport(string $format): ?object
{
return $this->reports[$format] ?? null;
}

/**
* @return array<string>
*/
public function getAvailableFormats(): array
{
return array_keys($this->reports);
}

public function hasReport(string $format): bool
{
return isset($this->reports[$format]);
}

public function count(): int
{
return count($this->reports);
}
}
Loading