Skip to content

Commit

Permalink
Treat all function signature nodes as 1-line range to avoid duplicate…
Browse files Browse the repository at this point in the history
… TestLocations (#1619)

Previously, `Node` of class `ClassMethod` returned a range for the whole method. Consider the following code:

```
class Test {
    public function findMe() // line 4
    {
        // ...
    } // line 7
}
```

for this code, `ClassMethod` node returned a [4, 7] range instead of [4, 4].

Because of this, later *for each line* (4, 5, 6, 7) we found all the test cases that cover them.

If we have 1 test case `TestClass::test_method_find_me` that covers `findMe()` method, then we returned 4 exactly the same duplicate test cases for `ClassMethod` mutation, one for each of (4, 5, 6, 7) lines.

After this update, only 1 test case is returned for the function signature mutant
  • Loading branch information
maks-rafalko committed Dec 21, 2021
1 parent af58050 commit c770354
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 6 deletions.
7 changes: 6 additions & 1 deletion src/TestFramework/Coverage/LineRangeCalculator.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
namespace Infection\TestFramework\Coverage;

use Infection\PhpParser\Visitor\ParentConnector;
use Infection\PhpParser\Visitor\ReflectionVisitor;
use PhpParser\Node;

/**
Expand All @@ -47,7 +48,11 @@ public function calculateRange(Node $node): NodeLineRangeData
{
$node = $this->getOuterMostArrayNode($node);

return new NodeLineRangeData($node->getStartLine(), $node->getEndLine());
$endLine = $node->getAttribute(ReflectionVisitor::IS_ON_FUNCTION_SIGNATURE, false) === true
? $node->getStartLine() // function signature node should always be 1-line range: (start, start)
: $node->getEndLine();

return new NodeLineRangeData($node->getStartLine(), $endLine);
}

/**
Expand Down
7 changes: 4 additions & 3 deletions src/TestFramework/Coverage/XmlReport/TestLocator.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
use Infection\TestFramework\Coverage\NodeLineRangeData;
use Infection\TestFramework\Coverage\SourceMethodLineRange;
use Infection\TestFramework\Coverage\TestLocations;
use Webmozart\Assert\Assert;

/**
* @internal
Expand Down Expand Up @@ -85,9 +86,9 @@ public function getAllTestsForMutation(
*/
private function getTestsForFunctionSignature(NodeLineRangeData $lineRange): iterable
{
foreach ($lineRange->range as $line) {
yield from $this->getTestsForExecutedMethodOnLine($line);
}
Assert::count($lineRange->range, 1); // 1-line range

yield from $this->getTestsForExecutedMethodOnLine($lineRange->range[0]);
}

/**
Expand Down
25 changes: 24 additions & 1 deletion tests/phpunit/TestFramework/Coverage/LineRangeCalculatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
namespace Infection\Tests\TestFramework\Coverage;

use Infection\PhpParser\Visitor\ParentConnectorVisitor;
use Infection\PhpParser\Visitor\ReflectionVisitor;
use Infection\TestFramework\Coverage\LineRangeCalculator;
use Infection\Tests\SingletonContainer;
use PhpParser\Node;
Expand Down Expand Up @@ -136,6 +137,21 @@ function foo(): void
,
[6],
];

yield 'function signature' => [
<<<'PHP'
<?php
class Test {
public function findMe() // line 4
{
// ...
}
}
PHP
,
[4],
];
}

private function createSpyTraverser()
Expand All @@ -144,10 +160,17 @@ private function createSpyTraverser()
/**
* @var int[]
*/
public $range = [];
public array $range = [];

public function leaveNode(Node $node)
{
if ($node instanceof Node\Stmt\ClassMethod && $node->name->name === 'findMe') {
$node->setAttribute(ReflectionVisitor::IS_ON_FUNCTION_SIGNATURE, true);

$lineRange = new LineRangeCalculator();
$this->range = $lineRange->calculateRange($node)->range;
}

if ($node instanceof Node\Expr\Variable && $node->name === 'findMe') {
$lineRange = new LineRangeCalculator();
$this->range = $lineRange->calculateRange($node)->range;
Expand Down
2 changes: 1 addition & 1 deletion tests/phpunit/TestFramework/Coverage/ProxyTraceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ public function test_it_exposes_its_test_locations(): void
$this->assertCount(
1,
iterator_to_array($trace->getAllTestsForMutation(
new NodeLineRangeData(19, 22),
new NodeLineRangeData(19, 19),
true
))
);
Expand Down

0 comments on commit c770354

Please sign in to comment.