Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

484: Add warning about Psalm baseline to readme + functional test #489

Open
wants to merge 11 commits into
base: 1.35.x
Choose a base branch
from
Open
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ composer require --dev roave/infection-static-analysis-plugin
vendor/bin/roave-infection-static-analysis-plugin
```

Do not use this tool if your project has a
[Psalm baseline](https://psalm.dev/docs/running_psalm/dealing_with_code_issues/#using-a-baseline-file) file. In that
case issues that are ignored due to being present in the baseline will be reported as killed, spuriously inflating your
mutation score indicator. See [issue #484](https://github.com/Roave/infection-static-analysis-plugin/issues/484).

### Configuration

The `roave-infection-static-analysis-plugin` binary accepts all of `infection` flags and arguments, and an additional `--psalm-config` argument.
Expand Down
4 changes: 2 additions & 2 deletions bin/roave-infection-static-analysis-plugin
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ use function var_export;
));
})();

require_once $projectPath . '/vendor/autoload.php';
require_once __DIR__ . '/../vendor/autoload.php';

if (! defined('PSALM_VERSION')) {
define('PSALM_VERSION', InstalledVersions::getVersion('vimeo/psalm'));
Expand All @@ -65,7 +65,7 @@ use function var_export;

RuntimeCaches::clearAll();

$configuration = $configuration ?? $projectPath;
$configuration ??= $projectPath;

if (is_file($configuration)) {
$config = Config::loadFromXMLFile($configuration, $projectPath);
Expand Down
5 changes: 4 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@
"autoload-dev": {
"psr-4": {
"Roave\\InfectionStaticAnalysisTest\\": "test/unit/Roave/InfectionStaticAnalysisTest"
}
},
"classmap": [
"test/asset/ProjectWithPsalmBaseline/src/HelloWorld.php"
]
},
"config": {
"allow-plugins": {
Expand Down
1 change: 1 addition & 0 deletions phpcs.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

<file>src</file>
<file>test</file>
<exclude-pattern>test/asset/ProjectWithPsalmBaseline</exclude-pattern>

<rule ref="Doctrine">
<!-- properties in psalm config do not use camel-case naming -->
Expand Down
2 changes: 1 addition & 1 deletion phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.1/phpunit.xsd"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="./vendor/autoload.php"
beStrictAboutChangesToGlobalState="true"
beStrictAboutCoverageMetadata="true"
Expand Down
19 changes: 12 additions & 7 deletions psalm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,18 @@
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
name="Example Psalm config with recommended defaults"
errorLevel="1"
findUnusedBaselineEntry="true"
findUnusedCode="true"
>
<projectFiles>
<directory name="bin"/>
<file name="bin/roave-infection-static-analysis-plugin"/>
<directory name="src"/>
<directory name="test"/>
<directory name="test/unit"/>
<ignoreFiles>
<directory name="test/asset/ProjectWithPsalmBaseline/src"/>
</ignoreFiles>
</projectFiles>

<issueHandlers>
<!--
we do a loooooooot of kinky stuff with infection's internals: that's by "design",
Expand Down Expand Up @@ -60,11 +65,11 @@
</errorLevel>
</PropertyNotSetInConstructor>

<!-- composer/package-versions-deprecated is in use by design -->
<DeprecatedClass>
<!-- phpunit tests are entry points - they are generally unused -->
<UnusedClass>
<errorLevel type="suppress">
<referencedClass name="PackageVersions\Versions"/>
<directory name="test"/>
</errorLevel>
</DeprecatedClass>
</UnusedClass>
</issueHandlers>
</psalm>
6 changes: 1 addition & 5 deletions src/Roave/InfectionStaticAnalysis/CliUtility.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,8 @@
use function substr;

/** @internal */
final class CliUtility
abstract class CliUtility
{
private function __construct()
{
}

/**
* @param list<non-empty-string> $arguments
* @param non-empty-string $argument
Expand Down
11 changes: 11 additions & 0 deletions test/asset/ProjectWithPsalmBaseline/infection.json5
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"$schema": "vendor/infection/infection/resources/schema.json",
"source": {
"directories": [
"src"
]
},
"mutators": {
"@default": true
}
}
11 changes: 11 additions & 0 deletions test/asset/ProjectWithPsalmBaseline/phpunit
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/usr/bin/env php
<?php
/**
* This file aliases the PHPUnit binary in the current directory.
*
* Without a discoverable executable, the `roave/infection-static-analysis`
* `bin/roave-infection-static-analysis-plugin` executable will otherwise
* fail to start up. It also emulates minimal autoloading.
*/

require __DIR__ . '/../../../vendor/bin/phpunit';
22 changes: 22 additions & 0 deletions test/asset/ProjectWithPsalmBaseline/phpunit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../vendor/phpunit/phpunit/phpunit.xsd"
cacheResult="false"
executionOrder="depends,defects"
requireCoverageMetadata="true"
beStrictAboutCoverageMetadata="true"
beStrictAboutOutputDuringTests="true"
failOnRisky="true"
failOnWarning="true">
<testsuites>
<testsuite name="default">
<directory>tests</directory>
</testsuite>
</testsuites>

<source restrictDeprecations="true" restrictNotices="true" restrictWarnings="true">
<include>
<directory>src</directory>
</include>
</source>
</phpunit>
17 changes: 17 additions & 0 deletions test/asset/ProjectWithPsalmBaseline/psalm-baseline.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="5.16.0@2897ba636551a8cb61601cc26f6ccfbba6c36591">
<file src="src/HelloWorld.php">
<MissingParamType>
<code>$mixture</code>
</MissingParamType>
<MixedInferredReturnType>
<code>int</code>
</MixedInferredReturnType>
<MixedOperand>
<code>$mixture</code>
</MixedOperand>
<MixedReturnStatement>
<code>$mixture + 2</code>
</MixedReturnStatement>
</file>
</files>
15 changes: 15 additions & 0 deletions test/asset/ProjectWithPsalmBaseline/psalm.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0"?>
<psalm
errorLevel="1"
resolveFromConfigFile="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config ../../../vendor/vimeo/psalm/config.xsd"
findUnusedBaselineEntry="true"
findUnusedCode="true"
errorBaseline="psalm-baseline.xml"
>
<projectFiles>
<directory name="src" />
</projectFiles>
</psalm>
19 changes: 19 additions & 0 deletions test/asset/ProjectWithPsalmBaseline/src/HelloWorld.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace Acme\ProjectWithPsalmBaseline;

/**
* @psalm-api
*/
class HelloWorld
{
/**
* This function has full test coverage, but the test is effectively assertion-free and useless. But
* because the function also has Psalm errors that are in the baseline, ISAP will think the test is good
* and give us a 100% MSI.
*/
public function takesImplictMixedReturnsIntAndIsCoveredByBaseline($mixture): int
{
return $mixture + 2;
}
}
17 changes: 17 additions & 0 deletions test/asset/ProjectWithPsalmBaseline/tests/HelloWorldTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

use Acme\ProjectWithPsalmBaseline\HelloWorld;

/**
* @covers \Acme\ProjectWithPsalmBaseline\HelloWorld
*/
class HelloWorldTest extends \PHPUnit\Framework\TestCase
{
public function testNothingButProvideCoverage(): void
{
$sut = new HelloWorld();
$_resultWeDontCheck = $sut->takesImplictMixedReturnsIntAndIsCoveredByBaseline(3);

$this->assertSame(4, 2+2);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

namespace Roave\InfectionStaticAnalysisTest;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Process\Process;

class ProjectWithBaselineTest extends TestCase
{
public function testItSpuriouslyReportsMutantAsKilledWithPsalmBaseline(): void
{
$process = new Process([__DIR__ . '/../../../../bin/roave-infection-static-analysis-plugin']);
$process->setWorkingDirectory(__DIR__ . '/../../../asset/ProjectWithPsalmBaseline');

$process->mustRun();

$output = $process->getOutput();

$this->assertSame(0, $process->getExitCode());
$this->assertStringContainsString('4 mutants were killed', $output);
$this->assertStringContainsString('Mutation Score Indicator (MSI): 100%', $output);
}
}