Skip to content

Commit 30b6142

Browse files
Add support for targeting traits
1 parent 08fbab6 commit 30b6142

File tree

7 files changed

+139
-3
lines changed

7 files changed

+139
-3
lines changed

src/Target/MapBuilder.php

+1
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ public function build(Filter $filter, FileAnalyser $analyser): array
181181

182182
return [
183183
'namespaces' => $namespaces,
184+
'traits' => $traits,
184185
'classes' => $classes,
185186
'classesThatExtendClass' => $classesThatExtendClass,
186187
'classesThatImplementInterface' => $classesThatImplementInterface,

src/Target/Mapper.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
use function array_unique;
1414

1515
/**
16-
* @phpstan-type TargetMap array{namespaces: TargetMapPart, classes: TargetMapPart, classesThatExtendClass: TargetMapPart, classesThatImplementInterface: TargetMapPart, methods: TargetMapPart, functions: TargetMapPart, reverseLookup: ReverseLookup}
16+
* @phpstan-type TargetMap array{namespaces: TargetMapPart, traits: TargetMapPart, classes: TargetMapPart, classesThatExtendClass: TargetMapPart, classesThatImplementInterface: TargetMapPart, methods: TargetMapPart, functions: TargetMapPart, reverseLookup: ReverseLookup}
1717
* @phpstan-type TargetMapPart array<non-empty-string, array<non-empty-string, list<positive-int>>>
1818
* @phpstan-type ReverseLookup array<non-empty-string, non-empty-string>
1919
*

src/Target/Target.php

+13
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,14 @@ public static function forFunction(string $functionName): Function_
6565
return new Function_($functionName);
6666
}
6767

68+
/**
69+
* @param trait-string $traitName
70+
*/
71+
public static function forTrait(string $traitName): Trait_
72+
{
73+
return new Trait_($traitName);
74+
}
75+
6876
public function isNamespace(): bool
6977
{
7078
return false;
@@ -95,6 +103,11 @@ public function isFunction(): bool
95103
return false;
96104
}
97105

106+
public function isTrait(): bool
107+
{
108+
return false;
109+
}
110+
98111
/**
99112
* @return non-empty-string
100113
*/

src/Target/Trait_.php

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php declare(strict_types=1);
2+
/*
3+
* This file is part of phpunit/php-code-coverage.
4+
*
5+
* (c) Sebastian Bergmann <[email protected]>
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
namespace SebastianBergmann\CodeCoverage\Test\Target;
11+
12+
/**
13+
* @immutable
14+
*
15+
* @no-named-arguments Parameter names are not covered by the backward compatibility promise for phpunit/php-code-coverage
16+
*/
17+
final class Trait_ extends Target
18+
{
19+
/**
20+
* @var trait-string
21+
*/
22+
private string $traitName;
23+
24+
/**
25+
* @param trait-string $traitName
26+
*/
27+
protected function __construct(string $traitName)
28+
{
29+
$this->traitName = $traitName;
30+
}
31+
32+
public function isTrait(): true
33+
{
34+
return true;
35+
}
36+
37+
/**
38+
* @return trait-string
39+
*/
40+
public function traitName(): string
41+
{
42+
return $this->traitName;
43+
}
44+
45+
/**
46+
* @return non-empty-string
47+
*/
48+
public function key(): string
49+
{
50+
return 'traits';
51+
}
52+
53+
/**
54+
* @return non-empty-string
55+
*/
56+
public function target(): string
57+
{
58+
return $this->traitName;
59+
}
60+
61+
/**
62+
* @return non-empty-string
63+
*/
64+
public function description(): string
65+
{
66+
return 'Trait ' . $this->target();
67+
}
68+
}

tests/tests/Target/MapBuilderTest.php

+5
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ public function testBuildsMap(): void
5757
),
5858
],
5959
],
60+
'traits' => [
61+
'SebastianBergmann\\CodeCoverage\\StaticAnalysis\\T' => [
62+
$file => range(19, 24),
63+
],
64+
],
6065
'classes' => [
6166
'SebastianBergmann\\CodeCoverage\\StaticAnalysis\\ParentClass' => [
6267
$file => range(26, 31),

tests/tests/Target/MapperTest.php

+23-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use PHPUnit\Framework\TestCase;
2121
use SebastianBergmann\CodeCoverage\Filter;
2222
use SebastianBergmann\CodeCoverage\StaticAnalysis\ParsingFileAnalyser;
23+
use SebastianBergmann\CodeCoverage\TestFixture\Target\TraitOne;
2324

2425
/**
2526
* @phpstan-import-type TargetMap from Mapper
@@ -83,6 +84,16 @@ public static function provider(): array
8384
],
8485
),
8586
],
87+
'trait' => [
88+
[
89+
realpath(__DIR__ . '/../../_files/Target/TraitOne.php') => range(4, 9),
90+
],
91+
TargetCollection::fromArray(
92+
[
93+
Target::forTrait(TraitOne::class),
94+
],
95+
),
96+
],
8697
'function' => [
8798
[
8899
$file => range(54, 56),
@@ -93,7 +104,7 @@ public static function provider(): array
93104
],
94105
),
95106
],
96-
'method' => [
107+
'method of class' => [
97108
[
98109
$file => range(37, 39),
99110
],
@@ -103,7 +114,7 @@ public static function provider(): array
103114
],
104115
),
105116
],
106-
'methods' => [
117+
'methods of class' => [
107118
[
108119
$file => array_merge(range(37, 39), range(41, 43)),
109120
],
@@ -114,6 +125,16 @@ public static function provider(): array
114125
],
115126
),
116127
],
128+
'method of trait' => [
129+
[
130+
$file => range(21, 23),
131+
],
132+
TargetCollection::fromArray(
133+
[
134+
Target::forMethod('SebastianBergmann\\CodeCoverage\\StaticAnalysis\\T', 'four'),
135+
],
136+
),
137+
],
117138
'namespace' => [
118139
[
119140
$file => array_merge(

tests/tests/Target/TargetTest.php

+28
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use PHPUnit\Framework\TestCase;
1515
use SebastianBergmann\CodeCoverage\TestFixture\Target\TargetClass;
1616
use SebastianBergmann\CodeCoverage\TestFixture\Target\TargetInterface;
17+
use SebastianBergmann\CodeCoverage\TestFixture\Target\TraitOne;
1718

1819
#[CoversClass(Target::class)]
1920
#[CoversClass(Class_::class)]
@@ -22,6 +23,7 @@
2223
#[CoversClass(Function_::class)]
2324
#[CoversClass(Method::class)]
2425
#[CoversClass(Namespace_::class)]
26+
#[CoversClass(Trait_::class)]
2527
#[Small]
2628
final class TargetTest extends TestCase
2729
{
@@ -37,6 +39,7 @@ public function testCanBeClass(): void
3739
$this->assertFalse($target->isFunction());
3840
$this->assertFalse($target->isMethod());
3941
$this->assertFalse($target->isNamespace());
42+
$this->assertFalse($target->isTrait());
4043

4144
$this->assertSame($className, $target->className());
4245
$this->assertSame('classes', $target->key());
@@ -56,6 +59,7 @@ public function testCanBeClassesThatExtendClass(): void
5659
$this->assertFalse($target->isFunction());
5760
$this->assertFalse($target->isMethod());
5861
$this->assertFalse($target->isNamespace());
62+
$this->assertFalse($target->isTrait());
5963

6064
$this->assertSame($className, $target->className());
6165
$this->assertSame('classesThatExtendClass', $target->key());
@@ -75,6 +79,7 @@ public function testCanBeClassesThatImplementInterface(): void
7579
$this->assertFalse($target->isFunction());
7680
$this->assertFalse($target->isMethod());
7781
$this->assertFalse($target->isNamespace());
82+
$this->assertFalse($target->isTrait());
7883

7984
$this->assertSame($interfaceName, $target->interfaceName());
8085
$this->assertSame('classesThatImplementInterface', $target->key());
@@ -94,6 +99,7 @@ public function testCanBeFunction(): void
9499
$this->assertTrue($target->isFunction());
95100
$this->assertFalse($target->isMethod());
96101
$this->assertFalse($target->isNamespace());
102+
$this->assertFalse($target->isTrait());
97103

98104
$this->assertSame($functionName, $target->functionName());
99105
$this->assertSame('functions', $target->key());
@@ -114,6 +120,7 @@ public function testCanBeMethod(): void
114120
$this->assertFalse($target->isFunction());
115121
$this->assertTrue($target->isMethod());
116122
$this->assertFalse($target->isNamespace());
123+
$this->assertFalse($target->isTrait());
117124

118125
$this->assertSame($className, $target->className());
119126
$this->assertSame($methodName, $target->methodName());
@@ -134,10 +141,31 @@ public function testCanBeNamespace(): void
134141
$this->assertFalse($target->isFunction());
135142
$this->assertFalse($target->isMethod());
136143
$this->assertTrue($target->isNamespace());
144+
$this->assertFalse($target->isTrait());
137145

138146
$this->assertSame($namespace, $target->namespace());
139147
$this->assertSame('namespaces', $target->key());
140148
$this->assertSame($namespace, $target->target());
141149
$this->assertSame('Namespace ' . $namespace, $target->description());
142150
}
151+
152+
public function testCanBeTrait(): void
153+
{
154+
$traitName = TraitOne::class;
155+
156+
$target = Target::forTrait($traitName);
157+
158+
$this->assertTrue($target->isTrait());
159+
$this->assertFalse($target->isClass());
160+
$this->assertFalse($target->isClassesThatExtendClass());
161+
$this->assertFalse($target->isClassesThatImplementInterface());
162+
$this->assertFalse($target->isFunction());
163+
$this->assertFalse($target->isMethod());
164+
$this->assertFalse($target->isNamespace());
165+
166+
$this->assertSame($traitName, $target->traitName());
167+
$this->assertSame('traits', $target->key());
168+
$this->assertSame($traitName, $target->target());
169+
$this->assertSame('Trait ' . $traitName, $target->description());
170+
}
143171
}

0 commit comments

Comments
 (0)