Skip to content
Draft
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
68 changes: 68 additions & 0 deletions src/Test/Target/Directory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php declare(strict_types=1);
/*
* This file is part of phpunit/php-code-coverage.
*
* (c) Sebastian Bergmann <sebastian@phpunit.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SebastianBergmann\CodeCoverage\Test\Target;

/**
* @immutable
*
* @no-named-arguments Parameter names are not covered by the backward compatibility promise for phpunit/php-code-coverage
*/
final class Directory extends Target
{
/**
* @var non-empty-string
*/
private string $directory;

/**
* @param non-empty-string $directory
*/
protected function __construct(string $directory)
{
$this->directory = $directory;
}

public function isDirectory(): true
{
return true;
}

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

/**
* @return non-empty-string
*/
public function key(): string
{
return 'directories';
}

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

/**
* @return non-empty-string
*/
public function description(): string
{
return 'Directory ' . $this->target();
}
}
68 changes: 68 additions & 0 deletions src/Test/Target/DirectoryRecursively.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php declare(strict_types=1);
/*
* This file is part of phpunit/php-code-coverage.
*
* (c) Sebastian Bergmann <sebastian@phpunit.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SebastianBergmann\CodeCoverage\Test\Target;

/**
* @immutable
*
* @no-named-arguments Parameter names are not covered by the backward compatibility promise for phpunit/php-code-coverage
*/
final class DirectoryRecursively extends Target
{
/**
* @var non-empty-string
*/
private string $directory;

/**
* @param non-empty-string $directory
*/
protected function __construct(string $directory)
{
$this->directory = $directory;
}

public function isDirectoryRecursively(): true
{
return true;
}

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

/**
* @return non-empty-string
*/
public function key(): string
{
return 'directoriesRecursively';
}

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

/**
* @return non-empty-string
*/
public function description(): string
{
return 'Directory (recursively) ' . $this->target();
}
}
68 changes: 68 additions & 0 deletions src/Test/Target/File.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php declare(strict_types=1);
/*
* This file is part of phpunit/php-code-coverage.
*
* (c) Sebastian Bergmann <sebastian@phpunit.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SebastianBergmann\CodeCoverage\Test\Target;

/**
* @immutable
*
* @no-named-arguments Parameter names are not covered by the backward compatibility promise for phpunit/php-code-coverage
*/
final class File extends Target
{
/**
* @var non-empty-string
*/
private string $path;

/**
* @param non-empty-string $path
*/
protected function __construct(string $path)
{
$this->path = $path;
}

public function isFile(): true
{
return true;
}

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

/**
* @return non-empty-string
*/
public function key(): string
{
return 'files';
}

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

/**
* @return non-empty-string
*/
public function description(): string
{
return 'File ' . $this->target();
}
}
28 changes: 26 additions & 2 deletions src/Test/Target/MapBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use function array_slice;
use function array_unique;
use function count;
use function dirname;
use function explode;
use function implode;
use function range;
Expand Down Expand Up @@ -52,6 +53,9 @@ public function build(Filter $filter, FileAnalyser $analyser): array
$traits = [];
$methods = [];
$functions = [];
$files = [];
$directories = [];
$directoriesRecursively = [];
$reverseLookup = [];

foreach ($filter->files() as $file) {
Expand Down Expand Up @@ -118,8 +122,8 @@ public function build(Filter $filter, FileAnalyser $analyser): array
}
}

foreach ($namespaces as $namespace => $files) {
foreach (array_keys($files) as $file) {
foreach ($namespaces as $namespace => $filesInNamespace) {
foreach (array_keys($filesInNamespace) as $file) {
$namespaces[$namespace][$file] = array_unique($namespaces[$namespace][$file]);
}
}
Expand Down Expand Up @@ -158,6 +162,23 @@ public function build(Filter $filter, FileAnalyser $analyser): array
unset($classesThatExtendClass[$className]);
}

foreach ($filter->files() as $file) {
$lines = range(1, $analyser->analyse($file)->linesOfCode()->linesOfCode());

$files[$file] = [$file => $lines];

$parent = dirname($file);

$directories[$parent][$file] = $lines;

$ancestor = $parent;

while ($ancestor !== dirname($ancestor)) {
$directoriesRecursively[$ancestor][$file] = $lines;
$ancestor = dirname($ancestor);
}
}

return [
'namespaces' => $namespaces,
'traits' => $traits,
Expand All @@ -166,6 +187,9 @@ public function build(Filter $filter, FileAnalyser $analyser): array
'classesThatImplementInterface' => $classesThatImplementInterface,
'methods' => $methods,
'functions' => $functions,
'files' => $files,
'directories' => $directories,
'directoriesRecursively' => $directoriesRecursively,
'reverseLookup' => $reverseLookup,
];
}
Expand Down
13 changes: 12 additions & 1 deletion src/Test/Target/Mapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@
use function array_keys;
use function array_merge;
use function array_unique;
use function realpath;
use function strcasecmp;

/**
* @phpstan-type TargetMap array{namespaces: TargetMapPart, traits: TargetMapPart, classes: TargetMapPart, classesThatExtendClass: TargetMapPart, classesThatImplementInterface: TargetMapPart, methods: TargetMapPart, functions: TargetMapPart, reverseLookup: ReverseLookup}
* @phpstan-type TargetMap array{namespaces: TargetMapPart, traits: TargetMapPart, classes: TargetMapPart, classesThatExtendClass: TargetMapPart, classesThatImplementInterface: TargetMapPart, methods: TargetMapPart, functions: TargetMapPart, files: TargetMapPart, directories: TargetMapPart, directoriesRecursively: TargetMapPart, reverseLookup: ReverseLookup}
* @phpstan-type TargetMapPart array<non-empty-string, array<non-empty-string, list<positive-int>>>
* @phpstan-type ReverseLookup array<non-empty-string, non-empty-string>
*
Expand Down Expand Up @@ -73,6 +74,16 @@ public function mapTarget(Target $target): array
return $this->map[$target->key()][$target->target()];
}

if ($target->isFile() || $target->isDirectory() || $target->isDirectoryRecursively()) {
$resolved = realpath($target->target());

if ($resolved !== false && isset($this->map[$target->key()][$resolved])) {
return $this->map[$target->key()][$resolved];
}

throw new InvalidCodeCoverageTargetException($target);
}

foreach (array_keys($this->map[$target->key()]) as $key) {
if (strcasecmp($key, $target->target()) === 0) {
return $this->map[$target->key()][$key];
Expand Down
39 changes: 39 additions & 0 deletions src/Test/Target/Target.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,30 @@ public static function forTrait(string $traitName): Trait_
return new Trait_($traitName);
}

/**
* @param non-empty-string $path
*/
public static function forFile(string $path): File
{
return new File($path);
}

/**
* @param non-empty-string $directory
*/
public static function forDirectory(string $directory): Directory
{
return new Directory($directory);
}

/**
* @param non-empty-string $directory
*/
public static function forDirectoryRecursively(string $directory): DirectoryRecursively
{
return new DirectoryRecursively($directory);
}

public function isNamespace(): bool
{
return false;
Expand Down Expand Up @@ -108,6 +132,21 @@ public function isTrait(): bool
return false;
}

public function isFile(): bool
{
return false;
}

public function isDirectory(): bool
{
return false;
}

public function isDirectoryRecursively(): bool
{
return false;
}

/**
* @return non-empty-string
*/
Expand Down
3 changes: 3 additions & 0 deletions tests/_files/Target/file-target-tree/Subdir/Inner.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<?php declare(strict_types=1);

echo 'inner';
3 changes: 3 additions & 0 deletions tests/_files/Target/file-target-tree/Top.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<?php declare(strict_types=1);

echo 'top';
5 changes: 4 additions & 1 deletion tests/tests/FilterProcessorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ public function testUncoveredFilesFromFilterReturnsMultipleFiles(): void
}

/**
* @return array{namespaces: array<empty>, traits: array<empty>, classes: array<empty>, classesThatExtendClass: array<empty>, classesThatImplementInterface: array<empty>, methods: array<empty>, functions: array<empty>, reverseLookup: array<empty>}
* @return array{namespaces: array<empty>, traits: array<empty>, classes: array<empty>, classesThatExtendClass: array<empty>, classesThatImplementInterface: array<empty>, methods: array<empty>, functions: array<empty>, files: array<empty>, directories: array<empty>, directoriesRecursively: array<empty>, reverseLookup: array<empty>}
*/
private function emptyMap(): array
{
Expand All @@ -427,6 +427,9 @@ private function emptyMap(): array
'classesThatImplementInterface' => [],
'methods' => [],
'functions' => [],
'files' => [],
'directories' => [],
'directoriesRecursively' => [],
'reverseLookup' => [],
];
}
Expand Down
Loading
Loading