Skip to content

Commit

Permalink
More work on mapping code coverage targets to source locations
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastianbergmann committed Dec 7, 2024
1 parent 9549d36 commit c4ba7f2
Show file tree
Hide file tree
Showing 12 changed files with 228 additions and 61 deletions.
10 changes: 4 additions & 6 deletions src/Exception/InvalidCodeCoverageTargetException.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,20 @@
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SebastianBergmann\CodeCoverage;
namespace SebastianBergmann\CodeCoverage\Test\Target;

use function sprintf;
use RuntimeException;
use SebastianBergmann\CodeCoverage\Exception;

final class InvalidCodeCoverageTargetException extends RuntimeException implements Exception
{
/**
* @param non-empty-string $target
*/
public function __construct(string $target)
public function __construct(Target $target)
{
parent::__construct(
sprintf(
'%s is not a valid target for code coverage',
$target,
$target->description(),
),
);
}
Expand Down
18 changes: 17 additions & 1 deletion src/Target/Class_.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,24 @@ public function className(): string
/**
* @return non-empty-string
*/
public function asString(): string
public function key(): string
{
return 'classes';
}

/**
* @return non-empty-string
*/
public function target(): string
{
return $this->className;
}

/**
* @return non-empty-string
*/
public function description(): string
{
return 'Class ' . $this->target();
}
}
18 changes: 17 additions & 1 deletion src/Target/ClassesThatExtendClass.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,24 @@ public function className(): string
/**
* @return non-empty-string
*/
public function asString(): string
public function key(): string
{
return 'classesThatExtendClass';
}

/**
* @return non-empty-string
*/
public function target(): string
{
return $this->className;
}

/**
* @return non-empty-string
*/
public function description(): string
{
return 'Classes that extend class ' . $this->target();
}
}
18 changes: 17 additions & 1 deletion src/Target/ClassesThatImplementInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,24 @@ public function interfaceName(): string
/**
* @return non-empty-string
*/
public function asString(): string
public function key(): string
{
return 'classesThatImplementInterface';
}

/**
* @return non-empty-string
*/
public function target(): string
{
return $this->interfaceName;
}

/**
* @return non-empty-string
*/
public function description(): string
{
return 'Classes that implement interface ' . $this->target();
}
}
18 changes: 17 additions & 1 deletion src/Target/Function_.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,24 @@ public function functionName(): string
/**
* @return non-empty-string
*/
public function asString(): string
public function key(): string
{
return 'functions';
}

/**
* @return non-empty-string
*/
public function target(): string
{
return $this->functionName;
}

/**
* @return non-empty-string
*/
public function description(): string
{
return 'Function ' . $this->target();
}
}
25 changes: 5 additions & 20 deletions src/Target/Mapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,11 @@

use function array_merge;
use function array_unique;
use function assert;
use function sort;
use SebastianBergmann\CodeCoverage\InvalidCodeCoverageTargetException;

/**
* @phpstan-type TargetMap = array{namespaces: array<non-empty-string, list<positive-int>>, classes: array<non-empty-string, list<positive-int>>, classesThatExtendClass: array<non-empty-string, list<positive-int>>, classesThatImplementInterface: array<non-empty-string, list<positive-int>>, traits: array<non-empty-string, list<positive-int>>, methods: array<non-empty-string, list<positive-int>>, functions: array<non-empty-string, list<positive-int>>}
* @phpstan-type TargetMap = array{namespaces: TargetMapPart, classes: TargetMapPart, classesThatExtendClass: TargetMapPart, classesThatImplementInterface: TargetMapPart, traits: TargetMapPart, methods: TargetMapPart, functions: TargetMapPart}
* @phpstan-type TargetMapPart = array<non-empty-string, array<non-empty-string, list<positive-int>>>
*
* @immutable
*
Expand Down Expand Up @@ -70,24 +69,10 @@ public function map(TargetCollection $targets): array
*/
private function mapTarget(Target $target): array
{
if ($target->isClass()) {
assert($target instanceof Class_);

if (!isset($this->map['classes'][$target->asString()])) {
throw new InvalidCodeCoverageTargetException('Class ' . $target->asString());
}

return $this->map['classes'][$target->asString()];
if (!isset($this->map[$target->key()][$target->target()])) {
throw new InvalidCodeCoverageTargetException($target);
}

if ($target->isMethod()) {
assert($target instanceof Method);

if (!isset($this->map['methods'][$target->asString()])) {
throw new InvalidCodeCoverageTargetException('Method ' . $target->asString());
}

return $this->map['methods'][$target->asString()];
}
return $this->map[$target->key()][$target->target()];
}
}
18 changes: 17 additions & 1 deletion src/Target/Method.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,24 @@ public function methodName(): string
/**
* @return non-empty-string
*/
public function asString(): string
public function key(): string
{
return 'methods';
}

/**
* @return non-empty-string
*/
public function target(): string
{
return $this->className . '::' . $this->methodName;
}

/**
* @return non-empty-string
*/
public function description(): string
{
return 'Method ' . $this->target();
}
}
18 changes: 17 additions & 1 deletion src/Target/Namespace_.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,24 @@ public function namespace(): string
/**
* @return non-empty-string
*/
public function asString(): string
public function key(): string
{
return 'namespaces';
}

/**
* @return non-empty-string
*/
public function target(): string
{
return $this->namespace;
}

/**
* @return non-empty-string
*/
public function description(): string
{
return 'Namespace ' . $this->target();
}
}
12 changes: 11 additions & 1 deletion src/Target/Target.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,5 +98,15 @@ public function isFunction(): bool
/**
* @return non-empty-string
*/
abstract public function asString(): string;
abstract public function key(): string;

/**
* @return non-empty-string
*/
abstract public function target(): string;

/**
* @return non-empty-string
*/
abstract public function description(): string;
}
3 changes: 0 additions & 3 deletions tests/tests/Target/MapBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,6 @@ public function testBuildsMap(): void
);
}

/**
* @return array{namespaces: array<non-empty-string, list<positive-int>>, classes: array<non-empty-string, list<positive-int>>, classesThatExtendClass: array<non-empty-string, list<positive-int>>, classesThatImplementInterface: array<non-empty-string, list<positive-int>>, traits: array<non-empty-string, list<positive-int>>, methods: array<non-empty-string, list<positive-int>>, functions: array<non-empty-string, list<positive-int>>}
*/
private function map(array $files): array
{
$filter = new Filter;
Expand Down
Loading

0 comments on commit c4ba7f2

Please sign in to comment.