Skip to content

Commit d4597d0

Browse files
authored
Add measure feature (#38)
* kick of measure * reorder to enable measure even on 0
1 parent 62159ca commit d4597d0

10 files changed

+106
-24
lines changed

README.md

+25-5
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ The param type is defined, but property and return types are missing.
3434

3535
* 1 out of 3 = 33 % coverage
3636

37-
How do we get to the 100 %?
37+
Our code has only one third quality it could have. Let's get to 100 %!
3838

3939
```diff
4040
final class ConferenceFactory
@@ -52,7 +52,7 @@ How do we get to the 100 %?
5252
}
5353
```
5454

55-
This technique is very simple and useful to start with even on legacy project. You also know, how high coverage your project has right now.
55+
This technique is very simple to start even on legacy project. Also, you're now aware exactly how high coverage your project has.
5656

5757
<br>
5858

@@ -70,15 +70,35 @@ The package is available on PHP 7.2+ version in tagged releases.
7070

7171
With [PHPStan extension installer](https://github.com/phpstan/extension-installer), everything is ready to run.
7272

73-
Enable each item on their own with simple configuration:
73+
Enable each item on their own:
7474

75-
```neon
75+
```yaml
7676
# phpstan.neon
7777
parameters:
7878
type_coverage:
7979
return: 50
8080
param: 35.5
8181
property: 70
82-
# also, how many files has declare strict types
82+
```
83+
84+
## Measure Strict Declares coverage
85+
86+
Once you've reached 100 % type coverage, make use [your code is strict and uses types](https://tomasvotruba.com/blog/how-adding-type-declarations-makes-your-code-dangerous):
87+
88+
```php
89+
<?php
90+
91+
declare(strict_types=1);
92+
```
93+
94+
Again, raise level percent by percent in your own pace:
95+
96+
```yaml
97+
parameters:
98+
type_coverage:
8399
declare: 40
84100
```
101+
102+
<br>
103+
104+
Happy coding!

config/extension.neon

+5
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ parametersSchema:
1111
return: anyOf(schema(float(), nullable()), schema(int(), nullable()))
1212
param: anyOf(schema(float(), nullable()), schema(int(), nullable()))
1313
property: anyOf(schema(float(), nullable()), schema(int(), nullable()))
14+
15+
# measure
16+
measure: bool()
1417
])
1518

1619
# default parameters
@@ -28,6 +31,8 @@ parameters:
2831
param: null
2932
property: null
3033

34+
measure: false
35+
3136
services:
3237
- TomasVotruba\TypeCoverage\Formatter\TypeCoverageFormatter
3338
- TomasVotruba\TypeCoverage\CollectorDataNormalizer

phpstan.neon

+4-1
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,11 @@ parameters:
1717
param_type: 100
1818
property_type: 100
1919

20+
# only show final data, no error report
21+
# measure: true
2022

21-
checkGenericClassInNonGenericObjectType: false
23+
ignoreErrors:
24+
- identifier: missingType.generics
2225

2326
excludePaths:
2427
- "*/Fixture/*"

src/Collectors/DeclareCollector.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace TomasVotruba\TypeCoverage\Collectors;
66

77
use PhpParser\Node;
8+
use PhpParser\Node\Scalar\LNumber;
89
use PhpParser\Node\Stmt\Declare_;
910
use PHPStan\Analyser\Scope;
1011
use PHPStan\Collectors\Collector;
@@ -35,7 +36,7 @@ public function processNode(Node $node, Scope $scope): bool
3536
}
3637

3738
if (
38-
! $declare->value instanceof Node\Scalar\LNumber
39+
! $declare->value instanceof LNumber
3940
|| $declare->value->value !== 1
4041
) {
4142
return false;

src/Configuration.php

+5
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,9 @@ public function getRequiredDeclareLevel(): float|int
3333
{
3434
return $this->parameters['declare'];
3535
}
36+
37+
public function showOnlyMeasure(): bool
38+
{
39+
return $this->parameters['measure'];
40+
}
3641
}

src/Rules/DeclareCoverageRule.php

+20-10
Original file line numberDiff line numberDiff line change
@@ -45,19 +45,9 @@ public function processNode(Node $node, Scope $scope): array
4545
{
4646
$requiredDeclareLevel = $this->configuration->getRequiredDeclareLevel();
4747

48-
// not enabled
49-
if ($requiredDeclareLevel === 0) {
50-
return [];
51-
}
52-
5348
$declareCollector = $node->get(DeclareCollector::class);
5449
$totalPossibleDeclares = count($declareCollector);
5550

56-
// nothing to handle
57-
if ($totalPossibleDeclares === 0) {
58-
return [];
59-
}
60-
6151
$coveredDeclares = 0;
6252
$notCoveredDeclareFilePaths = [];
6353

@@ -72,6 +62,26 @@ public function processNode(Node $node, Scope $scope): array
7262

7363
$declareCoverage = ($coveredDeclares / $totalPossibleDeclares) * 100;
7464

65+
if ($this->configuration->showOnlyMeasure()) {
66+
return [
67+
sprintf(
68+
'Strict declares coverage is %.1f %% out of %d possible',
69+
$declareCoverage,
70+
$totalPossibleDeclares
71+
),
72+
];
73+
}
74+
75+
// not enabled
76+
if ($requiredDeclareLevel === 0) {
77+
return [];
78+
}
79+
80+
// nothing to handle
81+
if ($totalPossibleDeclares === 0) {
82+
return [];
83+
}
84+
7585
// we meet the limit, all good
7686
if ($declareCoverage >= $requiredDeclareLevel) {
7787
return [];

src/Rules/ParamTypeCoverageRule.php

+14-4
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,24 @@ public function getNodeType(): string
4646
*/
4747
public function processNode(Node $node, Scope $scope): array
4848
{
49-
if ($this->configuration->getRequiredParamTypeLevel() === 0) {
50-
return [];
51-
}
52-
5349
$paramTypeDeclarationCollector = $node->get(ParamTypeDeclarationCollector::class);
5450

5551
$typeCountAndMissingTypes = $this->collectorDataNormalizer->normalize($paramTypeDeclarationCollector);
5652

53+
if ($this->configuration->showOnlyMeasure()) {
54+
return [
55+
sprintf(
56+
'Param type coverage is %.1f %% out of %d possible',
57+
$typeCountAndMissingTypes->getCoveragePercentage(),
58+
$typeCountAndMissingTypes->getTotalCount()
59+
),
60+
];
61+
}
62+
63+
if ($this->configuration->getRequiredParamTypeLevel() === 0) {
64+
return [];
65+
}
66+
5767
return $this->typeCoverageFormatter->formatErrors(
5868
self::ERROR_MESSAGE,
5969
$this->configuration->getRequiredParamTypeLevel(),

src/Rules/PropertyTypeCoverageRule.php

+13-3
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,23 @@ public function getNodeType(): string
4646
*/
4747
public function processNode(Node $node, Scope $scope): array
4848
{
49+
$propertyTypeDeclarationCollector = $node->get(PropertyTypeDeclarationCollector::class);
50+
$typeCountAndMissingTypes = $this->collectorDataNormalizer->normalize($propertyTypeDeclarationCollector);
51+
52+
if ($this->configuration->showOnlyMeasure()) {
53+
return [
54+
sprintf(
55+
'Property type coverage is %.1f %% out of %d possible',
56+
$typeCountAndMissingTypes->getCoveragePercentage(),
57+
$typeCountAndMissingTypes->getTotalCount()
58+
),
59+
];
60+
}
61+
4962
if ($this->configuration->getRequiredPropertyTypeLevel() === 0) {
5063
return [];
5164
}
5265

53-
$propertyTypeDeclarationCollector = $node->get(PropertyTypeDeclarationCollector::class);
54-
$typeCountAndMissingTypes = $this->collectorDataNormalizer->normalize($propertyTypeDeclarationCollector);
55-
5666
return $this->typeCoverageFormatter->formatErrors(
5767
self::ERROR_MESSAGE,
5868
$this->configuration->getRequiredPropertyTypeLevel(),

src/Rules/ReturnTypeCoverageRule.php

+14
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,20 @@ public function processNode(Node $node, Scope $scope): array
4949
$returnSeaLevelDataByFilePath = $node->get(ReturnTypeDeclarationCollector::class);
5050
$typeCountAndMissingTypes = $this->collectorDataNormalizer->normalize($returnSeaLevelDataByFilePath);
5151

52+
if ($this->configuration->showOnlyMeasure()) {
53+
return [
54+
sprintf(
55+
'Return type coverage is %.1f %% out of %d possible',
56+
$typeCountAndMissingTypes->getCoveragePercentage(),
57+
$typeCountAndMissingTypes->getTotalCount()
58+
),
59+
];
60+
}
61+
62+
if ($this->configuration->getRequiredReturnTypeLevel() === 0) {
63+
return [];
64+
}
65+
5266
return $this->typeCoverageFormatter->formatErrors(
5367
self::ERROR_MESSAGE,
5468
$this->configuration->getRequiredReturnTypeLevel(),

src/ValueObject/TypeCountAndMissingTypes.php

+4
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ public function getMissingTypeLinesByFilePath(): array
3636

3737
public function getCoveragePercentage(): float
3838
{
39+
if ($this->totalCount === 0) {
40+
return 100.0;
41+
}
42+
3943
$relative = 100 * ($this->getTypedCount() / $this->totalCount);
4044

4145
// round down with one decimal, to make error message clear that required value is not reached yet

0 commit comments

Comments
 (0)