diff --git a/infection.json b/infection.json index 789682b19..904efee14 100644 --- a/infection.json +++ b/infection.json @@ -7,8 +7,8 @@ ] }, "logs": { - "badge": { - "branch": "master" + "stryker": { + "badge": "master" } }, "mutators": { diff --git a/resources/schema.json b/resources/schema.json index e583f4a3d..4d761f757 100644 --- a/resources/schema.json +++ b/resources/schema.json @@ -70,26 +70,27 @@ "type": "string", "description": "Markdown file which will give a break-down of the effectiveness of each mutator." }, - "badge": { - "type": "object", - "description": "Mutation score badge for your GitHub project. If provided, infection will report results for maching branches to an upstream reporting dashboard/collector.", - "additionalProperties": false, - "required": ["branch"], - "properties": { - "branch": { - "type": "string", - "description": "Mutation score badge for your GitHub project. If this value starts and ends with \"/\", it will be considered a regular expression.", - "exaples": [ - "main", - "master", - "develop", - "latest", - "/1\\.\\d+/", - "/release-.*/", - "/feature\\/.*/" - ] + "stryker": { + "oneOf": [ + { + "type": "object", + "required": ["badge"], + "description": "Mutation score badge for your GitHub project. If provided, Infection will report results for matching branches to an upstream reporting dashboard.", + "additionalProperties": false, + "properties": { + "badge": { "$ref": "#/definitions/stryker-branch" } + } + }, + { + "type": "object", + "required": ["report"], + "description": "Mutation score badge for your GitHub project. If provided, Infection will report results for matching branches to an upstream reporting dashboard.", + "additionalProperties": false, + "properties": { + "report": { "$ref": "#/definitions/stryker-branch" } + } } - } + ] }, "github": { "type": "boolean", @@ -603,6 +604,19 @@ } } ] + }, + "stryker-branch": { + "type": "string", + "description": "Mutation score badge for your GitHub project. If this value starts and ends with \"/\", it will be considered a regular expression.", + "examples": [ + "main", + "master", + "develop", + "latest", + "/1\\.\\d+/", + "/release-.*/", + "/feature\\/.*/" + ] } } } diff --git a/src/Configuration/Entry/Logs.php b/src/Configuration/Entry/Logs.php index bc511685f..510a2e816 100644 --- a/src/Configuration/Entry/Logs.php +++ b/src/Configuration/Entry/Logs.php @@ -48,7 +48,7 @@ class Logs private ?string $debugLogFilePath; private ?string $perMutatorFilePath; private bool $useGitHubAnnotationsLogger; - private ?Badge $badge; + private ?StrykerConfig $strykerConfig; public function __construct( ?string $textLogFilePath, @@ -58,7 +58,7 @@ public function __construct( ?string $debugLogFilePath, ?string $perMutatorFilePath, bool $useGitHubAnnotationsLogger, - ?Badge $badge + ?StrykerConfig $strykerConfig ) { $this->textLogFilePath = $textLogFilePath; $this->htmlLogFilePath = $htmlLogFilePath; @@ -67,7 +67,7 @@ public function __construct( $this->debugLogFilePath = $debugLogFilePath; $this->perMutatorFilePath = $perMutatorFilePath; $this->useGitHubAnnotationsLogger = $useGitHubAnnotationsLogger; - $this->badge = $badge; + $this->strykerConfig = $strykerConfig; } public static function createEmpty(): self @@ -129,8 +129,8 @@ public function getUseGitHubAnnotationsLogger(): bool return $this->useGitHubAnnotationsLogger; } - public function getBadge(): ?Badge + public function getStrykerConfig(): ?StrykerConfig { - return $this->badge; + return $this->strykerConfig; } } diff --git a/src/Configuration/Entry/Badge.php b/src/Configuration/Entry/StrykerConfig.php similarity index 81% rename from src/Configuration/Entry/Badge.php rename to src/Configuration/Entry/StrykerConfig.php index 76a573f84..d7812642b 100644 --- a/src/Configuration/Entry/Badge.php +++ b/src/Configuration/Entry/StrykerConfig.php @@ -44,15 +44,22 @@ /** * @internal */ -final class Badge +final class StrykerConfig { private string $branchMatch; + private bool $isForFullReport; /** + * Stryker has 2 ways for integration (https://stryker-mutator.io/docs/General/dashboard): + * - badge only + * - full report + * * @throws InvalidArgumentException when the provided $branch looks like a regular expression, but is not a valid one */ - public function __construct(string $branch) + private function __construct(string $branch, bool $isForFullReport) { + $this->isForFullReport = $isForFullReport; + if (preg_match('#^/.+/$#', $branch) === 0) { $this->branchMatch = '/^' . preg_quote($branch, '/') . '$/'; @@ -73,6 +80,21 @@ public function __construct(string $branch) $this->branchMatch = $branch; } + public static function forBadge(string $branch): self + { + return new self($branch, false); + } + + public static function forFullReport(string $branch): self + { + return new self($branch, true); + } + + public function isForFullReport(): bool + { + return $this->isForFullReport; + } + public function applicableForBranch(string $branchName): bool { return preg_match($this->branchMatch, $branchName) === 1; diff --git a/src/Configuration/Schema/SchemaConfigurationFactory.php b/src/Configuration/Schema/SchemaConfigurationFactory.php index 2c0afcb60..fa3fda17e 100644 --- a/src/Configuration/Schema/SchemaConfigurationFactory.php +++ b/src/Configuration/Schema/SchemaConfigurationFactory.php @@ -38,10 +38,10 @@ use function array_filter; use function array_map; use function array_values; -use Infection\Configuration\Entry\Badge; use Infection\Configuration\Entry\Logs; use Infection\Configuration\Entry\PhpUnit; use Infection\Configuration\Entry\Source; +use Infection\Configuration\Entry\StrykerConfig; use stdClass; use function trim; @@ -88,18 +88,27 @@ private static function createLogs(stdClass $logs): Logs self::normalizeString($logs->debug ?? null), self::normalizeString($logs->perMutator ?? null), $logs->github ?? false, - self::createBadge($logs->badge ?? null) + self::createStrykerConfig($logs->stryker ?? null) ); } - private static function createBadge(?stdClass $badge): ?Badge + private static function createStrykerConfig(?stdClass $stryker): ?StrykerConfig { - $branch = self::normalizeString($badge->branch ?? null); + if ($stryker === null) { + return null; + } + + $branch = self::normalizeString($stryker->badge ?? $stryker->report ?? null); + + if ($branch === null) { + return null; + } + + if (($stryker->badge ?? null) !== null) { + return StrykerConfig::forBadge($branch); + } - return $branch === null - ? null - : new Badge($branch) - ; + return StrykerConfig::forFullReport($branch); } private static function createPhpUnit(stdClass $phpUnit): PhpUnit diff --git a/src/Container.php b/src/Container.php index 864720a06..f72d0a675 100644 --- a/src/Container.php +++ b/src/Container.php @@ -78,12 +78,12 @@ use Infection\FileSystem\SourceFileCollector; use Infection\FileSystem\SourceFileFilter; use Infection\FileSystem\TmpDirProvider; -use Infection\Logger\BadgeLoggerFactory; use Infection\Logger\FederatedLogger; use Infection\Logger\FileLoggerFactory; use Infection\Logger\GitHub\GitDiffFileProvider; use Infection\Logger\Html\StrykerHtmlReportBuilder; use Infection\Logger\MutationTestingResultsLogger; +use Infection\Logger\StrykerLoggerFactory; use Infection\Metrics\FilteringResultsCollectorFactory; use Infection\Metrics\MetricsCalculator; use Infection\Metrics\MinMsiChecker; @@ -549,9 +549,10 @@ public static function create(): self FilesDiffChangedLines::class => static function (self $container): FilesDiffChangedLines { return new FilesDiffChangedLines($container->getDiffChangedLinesParser(), $container->getGitDiffFileProvider()); }, - BadgeLoggerFactory::class => static function (self $container): BadgeLoggerFactory { - return new BadgeLoggerFactory( + StrykerLoggerFactory::class => static function (self $container): StrykerLoggerFactory { + return new StrykerLoggerFactory( $container->getMetricsCalculator(), + $container->getStrykerHtmlReportBuilder(), $container->getCiDetector(), $container->getLogger() ); @@ -575,7 +576,7 @@ public static function create(): self $container->getFileLoggerFactory()->createFromLogEntries( $container->getConfiguration()->getLogs() ), - $container->getBadgeLoggerFactory()->createFromLogEntries( + $container->getStrykerLoggerFactory()->createFromLogEntries( $container->getConfiguration()->getLogs() ), ])); @@ -1168,9 +1169,9 @@ public function getFileLoggerFactory(): FileLoggerFactory return $this->get(FileLoggerFactory::class); } - public function getBadgeLoggerFactory(): BadgeLoggerFactory + public function getStrykerLoggerFactory(): StrykerLoggerFactory { - return $this->get(BadgeLoggerFactory::class); + return $this->get(StrykerLoggerFactory::class); } public function getMutationTestingResultsLogger(): MutationTestingResultsLogger diff --git a/src/Environment/StrykerApiKeyResolver.php b/src/Environment/StrykerApiKeyResolver.php index 79c9152b7..39aff996c 100644 --- a/src/Environment/StrykerApiKeyResolver.php +++ b/src/Environment/StrykerApiKeyResolver.php @@ -36,6 +36,7 @@ namespace Infection\Environment; use function array_key_exists; +use function array_slice; use function is_string; /** @@ -53,7 +54,8 @@ final class StrykerApiKeyResolver public function resolve(array $environment): string { $names = [ - 'INFECTION_BADGE_API_KEY', + 'INFECTION_BADGE_API_KEY', // deprecated + 'INFECTION_DASHBOARD_API_KEY', 'STRYKER_DASHBOARD_API_KEY', ]; @@ -65,6 +67,6 @@ public function resolve(array $environment): string return $environment[$name]; } - throw CouldNotResolveStrykerApiKey::from(...$names); + throw CouldNotResolveStrykerApiKey::from(...array_slice($names, 1)); } } diff --git a/src/Logger/Http/StrykerCurlClient.php b/src/Logger/Http/StrykerCurlClient.php index 1320b5896..d33939ee0 100644 --- a/src/Logger/Http/StrykerCurlClient.php +++ b/src/Logger/Http/StrykerCurlClient.php @@ -55,8 +55,8 @@ * @internal * @final * - * @see https://github.com/stryker-mutator/stryker-handbook/blob/master/dashboard.md#send-a-report-via-curl - * @see https://github.com/stryker-mutator/mutation-testing-elements/tree/master/packages/mutation-testing-report-schema + * @see https://stryker-mutator.io/docs/General/dashboard + * @see https://github.com/stryker-mutator/mutation-testing-elements/blob/master/packages/report-schema/src/mutation-testing-report-schema.json */ class StrykerCurlClient { diff --git a/src/Logger/Http/StrykerDashboardClient.php b/src/Logger/Http/StrykerDashboardClient.php index ef92b1899..0032e4297 100644 --- a/src/Logger/Http/StrykerDashboardClient.php +++ b/src/Logger/Http/StrykerDashboardClient.php @@ -37,7 +37,6 @@ use function in_array; use Psr\Log\LoggerInterface; -use function Safe\json_encode; use function Safe\sprintf; /** @@ -58,13 +57,13 @@ public function sendReport( string $repositorySlug, string $branch, string $apiKey, - float $mutationScore + string $reportJson ): void { $response = $this->client->request( $repositorySlug, $branch, $apiKey, - json_encode(['mutationScore' => $mutationScore]) + $reportJson ); $statusCode = $response->getStatusCode(); diff --git a/src/Logger/BadgeLogger.php b/src/Logger/StrykerLogger.php similarity index 80% rename from src/Logger/BadgeLogger.php rename to src/Logger/StrykerLogger.php index cff4a95d2..52b30ce52 100644 --- a/src/Logger/BadgeLogger.php +++ b/src/Logger/StrykerLogger.php @@ -36,41 +36,46 @@ namespace Infection\Logger; use function getenv; -use Infection\Configuration\Entry\Badge; +use Infection\Configuration\Entry\StrykerConfig; use Infection\Environment\BuildContextResolver; use Infection\Environment\CouldNotResolveBuildContext; use Infection\Environment\CouldNotResolveStrykerApiKey; use Infection\Environment\StrykerApiKeyResolver; +use Infection\Logger\Html\StrykerHtmlReportBuilder; use Infection\Logger\Http\StrykerDashboardClient; use Infection\Metrics\MetricsCalculator; use Psr\Log\LoggerInterface; +use function Safe\json_encode; use function Safe\sprintf; /** * @internal */ -final class BadgeLogger implements MutationTestingResultsLogger +final class StrykerLogger implements MutationTestingResultsLogger { private BuildContextResolver $buildContextResolver; private StrykerApiKeyResolver $strykerApiKeyResolver; private StrykerDashboardClient $strykerDashboardClient; private MetricsCalculator $metricsCalculator; - private Badge $badge; + private StrykerConfig $strykerConfig; private LoggerInterface $logger; + private StrykerHtmlReportBuilder $strykerHtmlReportBuilder; public function __construct( BuildContextResolver $buildContextResolver, StrykerApiKeyResolver $strykerApiKeyResolver, StrykerDashboardClient $strykerDashboardClient, MetricsCalculator $metricsCalculator, - Badge $badge, + StrykerHtmlReportBuilder $strykerHtmlReportBuilder, + StrykerConfig $strykerConfig, LoggerInterface $logger ) { $this->buildContextResolver = $buildContextResolver; $this->strykerApiKeyResolver = $strykerApiKeyResolver; $this->strykerDashboardClient = $strykerDashboardClient; $this->metricsCalculator = $metricsCalculator; - $this->badge = $badge; + $this->strykerHtmlReportBuilder = $strykerHtmlReportBuilder; + $this->strykerConfig = $strykerConfig; $this->logger = $logger; } @@ -86,9 +91,9 @@ public function log(): void $branch = $buildContext->branch(); - if (!$this->badge->applicableForBranch($branch)) { + if (!$this->strykerConfig->applicableForBranch($branch)) { $this->logReportWasNotSent(sprintf( - 'Branch "%s" does not match expected badge configuration', + 'Branch "%s" does not match expected Stryker configuration', $branch )); @@ -106,11 +111,16 @@ public function log(): void // All clear! $this->logger->warning('Sending dashboard report...'); + // note: full html report updates Badge value as well + $report = $this->strykerConfig->isForFullReport() + ? $this->strykerHtmlReportBuilder->build() + : ['mutationScore' => $this->metricsCalculator->getMutationScoreIndicator()]; + $this->strykerDashboardClient->sendReport( 'github.com/' . $buildContext->repositorySlug(), $branch, $apiKey, - $this->metricsCalculator->getMutationScoreIndicator() + json_encode($report) ); } diff --git a/src/Logger/BadgeLoggerFactory.php b/src/Logger/StrykerLoggerFactory.php similarity index 85% rename from src/Logger/BadgeLoggerFactory.php rename to src/Logger/StrykerLoggerFactory.php index e8c369670..884fbc620 100644 --- a/src/Logger/BadgeLoggerFactory.php +++ b/src/Logger/StrykerLoggerFactory.php @@ -38,6 +38,7 @@ use Infection\Configuration\Entry\Logs; use Infection\Environment\BuildContextResolver; use Infection\Environment\StrykerApiKeyResolver; +use Infection\Logger\Html\StrykerHtmlReportBuilder; use Infection\Logger\Http\StrykerCurlClient; use Infection\Logger\Http\StrykerDashboardClient; use Infection\Metrics\MetricsCalculator; @@ -48,31 +49,34 @@ * @internal * @final */ -class BadgeLoggerFactory +class StrykerLoggerFactory { private MetricsCalculator $metricsCalculator; + private StrykerHtmlReportBuilder $strykerHtmlReportBuilder; private CiDetector $ciDetector; private LoggerInterface $logger; public function __construct( MetricsCalculator $metricsCalculator, + StrykerHtmlReportBuilder $strykerHtmlReportBuilder, CiDetector $ciDetector, LoggerInterface $logger ) { $this->metricsCalculator = $metricsCalculator; $this->ciDetector = $ciDetector; $this->logger = $logger; + $this->strykerHtmlReportBuilder = $strykerHtmlReportBuilder; } public function createFromLogEntries(Logs $logConfig): ?MutationTestingResultsLogger { - $badge = $logConfig->getBadge(); + $strykerConfig = $logConfig->getStrykerConfig(); - if ($badge === null) { + if ($strykerConfig === null) { return null; } - return new BadgeLogger( + return new StrykerLogger( new BuildContextResolver($this->ciDetector), new StrykerApiKeyResolver(), new StrykerDashboardClient( @@ -80,7 +84,8 @@ public function createFromLogEntries(Logs $logConfig): ?MutationTestingResultsLo $this->logger ), $this->metricsCalculator, - $badge, + $this->strykerHtmlReportBuilder, + $strykerConfig, $this->logger ); } diff --git a/tests/phpunit/Configuration/ConfigurationAssertions.php b/tests/phpunit/Configuration/ConfigurationAssertions.php index d243b348c..356801177 100644 --- a/tests/phpunit/Configuration/ConfigurationAssertions.php +++ b/tests/phpunit/Configuration/ConfigurationAssertions.php @@ -105,7 +105,7 @@ private function assertConfigurationStateIs( $expectedLogs->getDebugLogFilePath(), $expectedLogs->getPerMutatorFilePath(), $expectedLogs->getUseGitHubAnnotationsLogger(), - $expectedLogs->getBadge() + $expectedLogs->getStrykerConfig() ); $this->assertSame($expectedLogVerbosity, $configuration->getLogVerbosity()); $this->assertSame($expectedTmpDir, $configuration->getTmpDir()); diff --git a/tests/phpunit/Configuration/ConfigurationFactoryTest.php b/tests/phpunit/Configuration/ConfigurationFactoryTest.php index e3fa52c25..a5810cf38 100644 --- a/tests/phpunit/Configuration/ConfigurationFactoryTest.php +++ b/tests/phpunit/Configuration/ConfigurationFactoryTest.php @@ -36,10 +36,10 @@ namespace Infection\Tests\Configuration; use Infection\Configuration\ConfigurationFactory; -use Infection\Configuration\Entry\Badge; use Infection\Configuration\Entry\Logs; use Infection\Configuration\Entry\PhpUnit; use Infection\Configuration\Entry\Source; +use Infection\Configuration\Entry\StrykerConfig; use Infection\Configuration\Schema\SchemaConfiguration; use Infection\FileSystem\SourceFileCollector; use Infection\FileSystem\TmpDirProvider; @@ -772,7 +772,7 @@ public function valueProvider(): iterable 'debug.log', 'mutator.log', true, - new Badge('master') + StrykerConfig::forFullReport('master') ), 'config/tmp', new PhpUnit( @@ -828,7 +828,7 @@ public function valueProvider(): iterable 'debug.log', 'mutator.log', true, - new Badge('master') + StrykerConfig::forFullReport('master') ), 'none', '/path/to/config/tmp/infection', diff --git a/tests/phpunit/Configuration/ConfigurationTest.php b/tests/phpunit/Configuration/ConfigurationTest.php index 0d7d3233d..5c17252f6 100644 --- a/tests/phpunit/Configuration/ConfigurationTest.php +++ b/tests/phpunit/Configuration/ConfigurationTest.php @@ -36,9 +36,9 @@ namespace Infection\Tests\Configuration; use Infection\Configuration\Configuration; -use Infection\Configuration\Entry\Badge; use Infection\Configuration\Entry\Logs; use Infection\Configuration\Entry\PhpUnit; +use Infection\Configuration\Entry\StrykerConfig; use Infection\Mutator\IgnoreConfig; use Infection\Mutator\IgnoreMutator; use Infection\Mutator\Mutator; @@ -215,7 +215,7 @@ public function valueProvider(): iterable 'debug.log', 'mutator.log', true, - new Badge('master') + StrykerConfig::forBadge('master') ), 'default', 'custom-dir', diff --git a/tests/phpunit/Configuration/Entry/LogsAssertions.php b/tests/phpunit/Configuration/Entry/LogsAssertions.php index 2e2ca9185..c4ccd7b70 100644 --- a/tests/phpunit/Configuration/Entry/LogsAssertions.php +++ b/tests/phpunit/Configuration/Entry/LogsAssertions.php @@ -35,8 +35,8 @@ namespace Infection\Tests\Configuration\Entry; -use Infection\Configuration\Entry\Badge; use Infection\Configuration\Entry\Logs; +use Infection\Configuration\Entry\StrykerConfig; trait LogsAssertions { @@ -49,7 +49,7 @@ private function assertLogsStateIs( ?string $expectedDebugLogFilePath, ?string $expectedPerMutatorFilePath, bool $expectedUseGitHubAnnotationsLogger, - ?Badge $expectedBadge + ?StrykerConfig $expectedStrykerConfig ): void { $this->assertSame($expectedTextLogFilePath, $logs->getTextLogFilePath()); $this->assertSame($expectedHtmlLogFilePath, $logs->getHtmlLogFilePath()); @@ -59,14 +59,14 @@ private function assertLogsStateIs( $this->assertSame($expectedPerMutatorFilePath, $logs->getPerMutatorFilePath()); $this->assertSame($expectedUseGitHubAnnotationsLogger, $logs->getUseGitHubAnnotationsLogger()); - $badge = $logs->getBadge(); + $strykerConfig = $logs->getStrykerConfig(); - if ($expectedBadge === null) { - $this->assertNull($badge); + if ($expectedStrykerConfig === null) { + $this->assertNull($strykerConfig); } else { - $this->assertNotNull($badge); + $this->assertNotNull($strykerConfig); - self::assertEquals($expectedBadge, $badge); + self::assertEquals($expectedStrykerConfig, $strykerConfig); } } } diff --git a/tests/phpunit/Configuration/Entry/LogsTest.php b/tests/phpunit/Configuration/Entry/LogsTest.php index a4db7eec3..46eeb1b80 100644 --- a/tests/phpunit/Configuration/Entry/LogsTest.php +++ b/tests/phpunit/Configuration/Entry/LogsTest.php @@ -35,8 +35,8 @@ namespace Infection\Tests\Configuration\Entry; -use Infection\Configuration\Entry\Badge; use Infection\Configuration\Entry\Logs; +use Infection\Configuration\Entry\StrykerConfig; use PHPUnit\Framework\TestCase; final class LogsTest extends TestCase @@ -54,7 +54,7 @@ public function test_it_can_be_instantiated( ?string $debugLogFilePath, ?string $perMutatorFilePath, bool $useGitHubAnnotationsLogger, - ?Badge $badge + ?StrykerConfig $strykerConfig ): void { $logs = new Logs( $textLogFilePath, @@ -64,7 +64,7 @@ public function test_it_can_be_instantiated( $debugLogFilePath, $perMutatorFilePath, $useGitHubAnnotationsLogger, - $badge + $strykerConfig ); $this->assertLogsStateIs( @@ -76,7 +76,7 @@ public function test_it_can_be_instantiated( $debugLogFilePath, $perMutatorFilePath, $useGitHubAnnotationsLogger, - $badge + $strykerConfig ); } @@ -118,7 +118,7 @@ public function valuesProvider(): iterable 'debug.log', 'perMutator.log', true, - new Badge('master'), + StrykerConfig::forBadge('master'), ]; } } diff --git a/tests/phpunit/Configuration/Entry/BadgeTest.php b/tests/phpunit/Configuration/Entry/StrykerConfigTest.php similarity index 94% rename from tests/phpunit/Configuration/Entry/BadgeTest.php rename to tests/phpunit/Configuration/Entry/StrykerConfigTest.php index 61f850f72..c87a94d2e 100644 --- a/tests/phpunit/Configuration/Entry/BadgeTest.php +++ b/tests/phpunit/Configuration/Entry/StrykerConfigTest.php @@ -35,18 +35,18 @@ namespace Infection\Tests\Configuration\Entry; -use Infection\Configuration\Entry\Badge; +use Infection\Configuration\Entry\StrykerConfig; use InvalidArgumentException; use PHPUnit\Framework\TestCase; -final class BadgeTest extends TestCase +final class StrykerConfigTest extends TestCase { /** @dataProvider branch_names_to_be_matched */ public function test_branch_match(string $branchName, string $branchMatch, bool $willMatch): void { $this->assertSame( $willMatch, - (new Badge($branchMatch)) + (StrykerConfig::forBadge($branchMatch)) ->applicableForBranch($branchName) ); } @@ -77,7 +77,7 @@ public function branch_names_to_be_matched(): array public function test_it_rejects_invalid_regex(): void { try { - new Badge('/[/'); + StrykerConfig::forBadge('/[/'); $this->fail(); } catch (InvalidArgumentException $invalid) { diff --git a/tests/phpunit/Configuration/Schema/SchemaConfigurationFactoryTest.php b/tests/phpunit/Configuration/Schema/SchemaConfigurationFactoryTest.php index 02a817ab1..4ca1472b4 100644 --- a/tests/phpunit/Configuration/Schema/SchemaConfigurationFactoryTest.php +++ b/tests/phpunit/Configuration/Schema/SchemaConfigurationFactoryTest.php @@ -42,10 +42,10 @@ use function array_merge; use function array_values; use function implode; -use Infection\Configuration\Entry\Badge; use Infection\Configuration\Entry\Logs; use Infection\Configuration\Entry\PhpUnit; use Infection\Configuration\Entry\Source; +use Infection\Configuration\Entry\StrykerConfig; use Infection\Configuration\Schema\SchemaConfiguration; use Infection\Configuration\Schema\SchemaConfigurationFactory; use Infection\Mutator\ProfileList; @@ -59,10 +59,10 @@ use function var_export; /** - * @covers \Infection\Configuration\Entry\Badge * @covers \Infection\Configuration\Entry\Logs * @covers \Infection\Configuration\Entry\PhpUnit * @covers \Infection\Configuration\Entry\Source + * @covers \Infection\Configuration\Entry\StrykerConfig * @covers \Infection\Configuration\Schema\SchemaConfigurationFactory */ final class SchemaConfigurationFactoryTest extends TestCase @@ -372,15 +372,15 @@ public function provideRawConfig(): iterable ]), ]; - yield '[logs][badge] nominal' => [ + yield '[logs][stryker] badge' => [ <<<'JSON' { "source": { "directories": ["src"] }, "logs": { - "badge": { - "branch": "master" + "stryker": { + "badge": "master" } } } @@ -396,20 +396,20 @@ public function provideRawConfig(): iterable null, null, false, - new Badge('master') + StrykerConfig::forBadge('master') ), ]), ]; - yield '[logs][badge] regex' => [ + yield '[logs][stryker] report' => [ <<<'JSON' { "source": { "directories": ["src"] }, "logs": { - "badge": { - "branch": "/^foo$/" + "stryker": { + "report": "master" } } } @@ -425,7 +425,65 @@ public function provideRawConfig(): iterable null, null, false, - new Badge('/^foo$/') + StrykerConfig::forFullReport('master') + ), + ]), + ]; + + yield '[logs][stryker] badge regex' => [ + <<<'JSON' +{ + "source": { + "directories": ["src"] + }, + "logs": { + "stryker": { + "badge": "/^foo$/" + } + } +} +JSON + , + self::createConfig([ + 'source' => new Source(['src'], []), + 'logs' => new Logs( + null, + null, + null, + null, + null, + null, + false, + StrykerConfig::forBadge('/^foo$/') + ), + ]), + ]; + + yield '[logs][stryker] report regex' => [ + <<<'JSON' +{ + "source": { + "directories": ["src"] + }, + "logs": { + "stryker": { + "report": "/^foo$/" + } + } +} +JSON + , + self::createConfig([ + 'source' => new Source(['src'], []), + 'logs' => new Logs( + null, + null, + null, + null, + null, + null, + false, + StrykerConfig::forFullReport('/^foo$/') ), ]), ]; @@ -444,8 +502,8 @@ public function provideRawConfig(): iterable "debug": "debug.log", "perMutator": "perMutator.log", "github": true, - "badge": { - "branch": "master" + "stryker": { + "badge": "master" } } } @@ -461,7 +519,7 @@ public function provideRawConfig(): iterable 'debug.log', 'perMutator.log', true, - new Badge('master') + StrykerConfig::forBadge('master') ), ]), ]; @@ -477,8 +535,8 @@ public function provideRawConfig(): iterable "summary": "", "debug": "", "perMutator": "", - "badge": { - "branch": "" + "stryker": { + "report": "" } } } @@ -501,8 +559,8 @@ public function provideRawConfig(): iterable "summary": "", "debug": "", "perMutator": "", - "badge": { - "branch": "" + "stryker": { + "badge": "" } } } @@ -528,8 +586,8 @@ public function provideRawConfig(): iterable "debug": " debug.log ", "perMutator": " perMutator.log ", "github": true , - "badge": { - "branch": " master " + "stryker": { + "badge": " master " } } } @@ -545,7 +603,7 @@ public function provideRawConfig(): iterable 'debug.log', 'perMutator.log', true, - new Badge('master') + StrykerConfig::forBadge('master') ), ]), ]; @@ -2178,8 +2236,8 @@ public function provideRawConfig(): iterable "debug": "debug.log", "perMutator": "perMutator.log", "github": true, - "badge": { - "branch": "master" + "stryker": { + "badge": "master" } }, "tmpDir": "custom-tmp", @@ -2417,7 +2475,7 @@ public function provideRawConfig(): iterable 'debug.log', 'perMutator.log', true, - new Badge('master') + StrykerConfig::forBadge('master') ), 'tmpDir' => 'custom-tmp', 'phpunit' => new PhpUnit( diff --git a/tests/phpunit/Configuration/Schema/SchemaConfigurationTest.php b/tests/phpunit/Configuration/Schema/SchemaConfigurationTest.php index 7cefcd901..d51ee48f6 100644 --- a/tests/phpunit/Configuration/Schema/SchemaConfigurationTest.php +++ b/tests/phpunit/Configuration/Schema/SchemaConfigurationTest.php @@ -35,10 +35,10 @@ namespace Infection\Tests\Configuration\Schema; -use Infection\Configuration\Entry\Badge; use Infection\Configuration\Entry\Logs; use Infection\Configuration\Entry\PhpUnit; use Infection\Configuration\Entry\Source; +use Infection\Configuration\Entry\StrykerConfig; use Infection\Configuration\Schema\SchemaConfiguration; use PHPUnit\Framework\TestCase; @@ -127,7 +127,7 @@ public function valueProvider(): iterable 'debug.log', 'mutator.log', true, - new Badge('master') + StrykerConfig::forFullReport('master') ), 'path/to/tmp', new PhpUnit('dist/phpunit', 'bin/phpunit'), diff --git a/tests/phpunit/Environment/StrykerApiKeyResolverTest.php b/tests/phpunit/Environment/StrykerApiKeyResolverTest.php index 495a3f362..3f42131f3 100644 --- a/tests/phpunit/Environment/StrykerApiKeyResolverTest.php +++ b/tests/phpunit/Environment/StrykerApiKeyResolverTest.php @@ -70,7 +70,7 @@ public function test_resolve_throws_when_value_of_known_environment_variables_is { $environment = [ 'API_KEY' => 'foo', - 'INFECTION_BADGE_API_KEY' => 9000, + 'INFECTION_DASHBOARD_API_KEY' => 9000, 'STRYKER_DASHBOARD_API_KEY' => new stdClass(), ]; @@ -85,7 +85,7 @@ public function test_resolve_returns_value_of_infection_badge_api_key_when_avail { $environment = [ 'API_KEY' => 'foo', - 'INFECTION_BADGE_API_KEY' => 'bar', + 'INFECTION_DASHBOARD_API_KEY' => 'bar', 'STRYKER_DASHBOARD_API_KEY' => 'baz', ]; diff --git a/tests/phpunit/Logger/FileLoggerFactoryTest.php b/tests/phpunit/Logger/FileLoggerFactoryTest.php index 8bb2bbc3d..b54d9bf8b 100644 --- a/tests/phpunit/Logger/FileLoggerFactoryTest.php +++ b/tests/phpunit/Logger/FileLoggerFactoryTest.php @@ -37,8 +37,8 @@ use function array_map; use function get_class; -use Infection\Configuration\Entry\Badge; use Infection\Configuration\Entry\Logs; +use Infection\Configuration\Entry\StrykerConfig; use Infection\Console\LogVerbosity; use Infection\Logger\DebugFileLogger; use Infection\Logger\FederatedLogger; @@ -244,7 +244,7 @@ public function logsProvider(): iterable 'debug', 'per_mutator', true, - new Badge('branch') + StrykerConfig::forBadge('branch') ), [ TextFileLogger::class, diff --git a/tests/phpunit/Logger/Http/StrykerDashboardClientTest.php b/tests/phpunit/Logger/Http/StrykerDashboardClientTest.php index eed8c01a3..873fb5f60 100644 --- a/tests/phpunit/Logger/Http/StrykerDashboardClientTest.php +++ b/tests/phpunit/Logger/Http/StrykerDashboardClientTest.php @@ -44,8 +44,6 @@ use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Psr\Log\LogLevel; -use function Safe\json_decode; -use function Safe\json_encode; final class StrykerDashboardClientTest extends TestCase { @@ -89,12 +87,7 @@ public function test_it_can_send_a_report_with_expected_response_status_code(): 'infection/infection', 'master', self::API_KEY, - json_encode(json_decode(<<<'JSON' -{ - "mutationScore": 80.31 -} -JSON - )) + '{"mutationScore": 80.31}' ) ->willReturn(new Response(201, 'Report received!')) ; @@ -103,7 +96,7 @@ public function test_it_can_send_a_report_with_expected_response_status_code(): 'infection/infection', 'master', self::API_KEY, - 80.31 + '{"mutationScore": 80.31}' ); $this->assertSame( @@ -138,12 +131,7 @@ public function test_it_issues_a_warning_when_the_report_could_not_be_sent(): vo 'infection/infection', 'master', self::API_KEY, - json_encode(json_decode(<<<'JSON' -{ - "mutationScore": 80.31 -} -JSON - )) + '{"mutationScore": 80.31}' ) ->willReturn(new Response(400, 'Report invalid!')) ; @@ -152,7 +140,7 @@ public function test_it_issues_a_warning_when_the_report_could_not_be_sent(): vo 'infection/infection', 'master', self::API_KEY, - 80.31 + '{"mutationScore": 80.31}' ); $this->assertSame( diff --git a/tests/phpunit/Logger/BadgeLoggerFactoryTest.php b/tests/phpunit/Logger/StrykerLoggerFactoryTest.php similarity index 80% rename from tests/phpunit/Logger/BadgeLoggerFactoryTest.php rename to tests/phpunit/Logger/StrykerLoggerFactoryTest.php index d7ddabb23..bd05efb63 100644 --- a/tests/phpunit/Logger/BadgeLoggerFactoryTest.php +++ b/tests/phpunit/Logger/StrykerLoggerFactoryTest.php @@ -37,14 +37,16 @@ use function array_map; use function get_class; -use Infection\Configuration\Entry\Badge; use Infection\Configuration\Entry\Logs; -use Infection\Logger\BadgeLogger; -use Infection\Logger\BadgeLoggerFactory; +use Infection\Configuration\Entry\StrykerConfig; use Infection\Logger\FederatedLogger; use Infection\Logger\FileLogger; +use Infection\Logger\Html\StrykerHtmlReportBuilder; use Infection\Logger\MutationTestingResultsLogger; +use Infection\Logger\StrykerLogger; +use Infection\Logger\StrykerLoggerFactory; use Infection\Metrics\MetricsCalculator; +use Infection\Metrics\ResultsCollector; use Infection\Tests\Fixtures\FakeCiDetector; use Infection\Tests\Fixtures\Logger\FakeLogger; use PHPUnit\Framework\TestCase; @@ -53,7 +55,7 @@ /** * @group integration */ -final class BadgeLoggerFactoryTest extends TestCase +final class StrykerLoggerFactoryTest extends TestCase { public function test_it_does_not_create_any_logger_for_no_verbosity_level_and_no_badge(): void { @@ -75,7 +77,7 @@ public function test_it_does_not_create_any_logger_for_no_verbosity_level_and_no $this->assertNull($logger); } - public function test_it_creates_a_badge_logger_on_no_verbosity(): void + public function test_it_creates_a_stryker_logger_on_no_verbosity(): void { $factory = $this->createLoggerFactory(); @@ -88,11 +90,11 @@ public function test_it_creates_a_badge_logger_on_no_verbosity(): void null, null, false, - new Badge('master') + StrykerConfig::forBadge('master') ) ); - $this->assertInstanceOf(BadgeLogger::class, $logger); + $this->assertInstanceOf(StrykerLogger::class, $logger); } /** @@ -122,7 +124,7 @@ public function logsProvider(): iterable null, ]; - yield 'badge logger' => [ + yield 'stryker for badge logger' => [ new Logs( null, null, @@ -131,9 +133,23 @@ public function logsProvider(): iterable null, null, false, - new Badge('foo') + StrykerConfig::forBadge('foo') ), - BadgeLogger::class, + StrykerLogger::class, + ]; + + yield 'stryker for report logger' => [ + new Logs( + null, + null, + null, + null, + null, + null, + false, + StrykerConfig::forFullReport('foo') + ), + StrykerLogger::class, ]; yield 'all loggers' => [ @@ -145,16 +161,19 @@ public function logsProvider(): iterable 'debug', 'per_mutator', true, - new Badge('branch') + StrykerConfig::forBadge('branch') ), - BadgeLogger::class, + StrykerLogger::class, ]; } - private function createLoggerFactory(): BadgeLoggerFactory + private function createLoggerFactory(): StrykerLoggerFactory { - return new BadgeLoggerFactory( + $metricsCalculator = new MetricsCalculator(2); + + return new StrykerLoggerFactory( new MetricsCalculator(2), + new StrykerHtmlReportBuilder($metricsCalculator, new ResultsCollector()), new FakeCiDetector(), new FakeLogger(), ); diff --git a/tests/phpunit/Logger/BadgeLoggerTest.php b/tests/phpunit/Logger/StrykerLoggerTest.php similarity index 72% rename from tests/phpunit/Logger/BadgeLoggerTest.php rename to tests/phpunit/Logger/StrykerLoggerTest.php index 52d3a0375..78b648e8d 100644 --- a/tests/phpunit/Logger/BadgeLoggerTest.php +++ b/tests/phpunit/Logger/StrykerLoggerTest.php @@ -35,12 +35,14 @@ namespace Infection\Tests\Logger; -use Infection\Configuration\Entry\Badge; +use Infection\Configuration\Entry\StrykerConfig; use Infection\Environment\BuildContextResolver; use Infection\Environment\StrykerApiKeyResolver; -use Infection\Logger\BadgeLogger; +use Infection\Logger\Html\StrykerHtmlReportBuilder; use Infection\Logger\Http\StrykerDashboardClient; +use Infection\Logger\StrykerLogger; use Infection\Metrics\MetricsCalculator; +use Infection\Metrics\ResultsCollector; use Infection\Tests\CI\ConfigurableEnv; use Infection\Tests\EnvVariableManipulation\BacksUpEnvironmentVariables; use OndraM\CiDetector\CiDetector; @@ -49,14 +51,14 @@ use Psr\Log\LogLevel; use function Safe\putenv; -final class BadgeLoggerTest extends TestCase +final class StrykerLoggerTest extends TestCase { use BacksUpEnvironmentVariables; /** * @var StrykerDashboardClient|MockObject */ - private $badgeApiClientMock; + private $strykerDashboardClient; /** * @var MetricsCalculator|MockObject @@ -74,25 +76,26 @@ final class BadgeLoggerTest extends TestCase private $logger; /** - * @var BadgeLogger + * @var StrykerLogger */ - private $badgeLogger; + private $strykerLogger; protected function setUp(): void { $this->backupEnvironmentVariables(); - $this->badgeApiClientMock = $this->createMock(StrykerDashboardClient::class); + $this->strykerDashboardClient = $this->createMock(StrykerDashboardClient::class); $this->metricsCalculatorMock = $this->createMock(MetricsCalculator::class); $this->ciDetectorEnv = new ConfigurableEnv(); $this->logger = new DummyLogger(); - $this->badgeLogger = new BadgeLogger( + $this->strykerLogger = new StrykerLogger( new BuildContextResolver(CiDetector::fromEnvironment($this->ciDetectorEnv)), new StrykerApiKeyResolver(), - $this->badgeApiClientMock, + $this->strykerDashboardClient, $this->metricsCalculatorMock, - new Badge('master'), + new StrykerHtmlReportBuilder($this->metricsCalculatorMock, new ResultsCollector()), + StrykerConfig::forBadge('master'), $this->logger ); } @@ -108,12 +111,12 @@ public function test_it_skips_logging_when_it_is_not_travis(): void 'TRAVIS' => false, ]); - $this->badgeApiClientMock + $this->strykerDashboardClient ->expects($this->never()) ->method('sendReport') ; - $this->badgeLogger->log(); + $this->strykerLogger->log(); $this->assertSame( [ @@ -134,12 +137,12 @@ public function test_it_skips_logging_when_it_is_pull_request(): void 'TRAVIS_PULL_REQUEST' => '123', ]); - $this->badgeApiClientMock + $this->strykerDashboardClient ->expects($this->never()) ->method('sendReport') ; - $this->badgeLogger->log(); + $this->strykerLogger->log(); $this->assertSame( [ @@ -162,11 +165,11 @@ public function test_it_skips_logging_when_branch_not_found(): void 'TRAVIS_BRANCH' => false, ]); - $this->badgeApiClientMock + $this->strykerDashboardClient ->expects($this->never()) ->method('sendReport'); - $this->badgeLogger->log(); + $this->strykerLogger->log(); $this->assertSame( [ @@ -189,12 +192,12 @@ public function test_it_skips_logging_when_repo_slug_not_found(): void 'TRAVIS_BRANCH' => 'foo', ]); - $this->badgeApiClientMock + $this->strykerDashboardClient ->expects($this->never()) ->method('sendReport') ; - $this->badgeLogger->log(); + $this->strykerLogger->log(); $this->assertSame( [ @@ -217,18 +220,18 @@ public function test_it_skips_logging_when_it_is_branch_not_from_config(): void 'TRAVIS_BRANCH' => 'foo', ]); - $this->badgeApiClientMock + $this->strykerDashboardClient ->expects($this->never()) ->method('sendReport') ; - $this->badgeLogger->log(); + $this->strykerLogger->log(); $this->assertSame( [ [ LogLevel::WARNING, - 'Dashboard report has not been sent: Branch "foo" does not match expected badge configuration', + 'Dashboard report has not been sent: Branch "foo" does not match expected Stryker configuration', [], ], ], @@ -245,27 +248,28 @@ public function test_it_skips_logging_when_it_is_branch_not_from_config_regex(): 'TRAVIS_BRANCH' => '1.x-mismatch', ]); - $this->badgeApiClientMock + $this->strykerDashboardClient ->expects($this->never()) ->method('sendReport') ; - $badgeLogger = new BadgeLogger( + $strykerLogger = new StrykerLogger( new BuildContextResolver(CiDetector::fromEnvironment($this->ciDetectorEnv)), new StrykerApiKeyResolver(), - $this->badgeApiClientMock, + $this->strykerDashboardClient, $this->metricsCalculatorMock, - new Badge('/^\d+\\.x$/'), + new StrykerHtmlReportBuilder($this->metricsCalculatorMock, new ResultsCollector()), + StrykerConfig::forBadge('/^\d+\\.x$/'), $this->logger ); - $badgeLogger->log(); + $strykerLogger->log(); $this->assertSame( [ [ LogLevel::WARNING, - 'Dashboard report has not been sent: Branch "1.x-mismatch" does not match expected badge configuration', + 'Dashboard report has not been sent: Branch "1.x-mismatch" does not match expected Stryker configuration', [], ], ], @@ -282,21 +286,21 @@ public function test_it_sends_report_missing_our_api_key(): void 'TRAVIS_BRANCH' => 'master', ]); - putenv('INFECTION_BADGE_API_KEY'); + putenv('INFECTION_DASHBOARD_API_KEY'); putenv('STRYKER_DASHBOARD_API_KEY'); - $this->badgeApiClientMock + $this->strykerDashboardClient ->expects($this->never()) ->method('sendReport') ; - $this->badgeLogger->log(); + $this->strykerLogger->log(); $this->assertSame( [ [ LogLevel::WARNING, - 'Dashboard report has not been sent: The Stryker API key needs to be configured using one of the environment variables "INFECTION_BADGE_API_KEY" or "STRYKER_DASHBOARD_API_KEY", but could not find any of these.', + 'Dashboard report has not been sent: The Stryker API key needs to be configured using one of the environment variables "INFECTION_DASHBOARD_API_KEY" or "STRYKER_DASHBOARD_API_KEY", but could not find any of these.', [], ], ], @@ -315,10 +319,10 @@ public function test_it_sends_report_when_everything_is_ok_with_stryker_key(): v putenv('STRYKER_DASHBOARD_API_KEY=abc'); - $this->badgeApiClientMock + $this->strykerDashboardClient ->expects($this->once()) ->method('sendReport') - ->with('github.com/a/b', 'master', 'abc', 33.3) + ->with('github.com/a/b', 'master', 'abc', '{"mutationScore":33.3}') ; $this->metricsCalculatorMock @@ -326,7 +330,7 @@ public function test_it_sends_report_when_everything_is_ok_with_stryker_key(): v ->willReturn(33.3) ; - $this->badgeLogger->log(); + $this->strykerLogger->log(); $this->assertSame( [ @@ -351,10 +355,10 @@ public function test_it_sends_report_when_everything_is_ok_with_stryker_key_and_ putenv('STRYKER_DASHBOARD_API_KEY=abc'); - $this->badgeApiClientMock + $this->strykerDashboardClient ->expects($this->once()) ->method('sendReport') - ->with('github.com/a/b', '7.x', 'abc', 33.3) + ->with('github.com/a/b', '7.x', 'abc', '{"mutationScore":33.3}') ; $this->metricsCalculatorMock @@ -362,16 +366,17 @@ public function test_it_sends_report_when_everything_is_ok_with_stryker_key_and_ ->willReturn(33.3) ; - $badgeLogger = new BadgeLogger( + $strykerLogger = new StrykerLogger( new BuildContextResolver(CiDetector::fromEnvironment($this->ciDetectorEnv)), new StrykerApiKeyResolver(), - $this->badgeApiClientMock, + $this->strykerDashboardClient, $this->metricsCalculatorMock, - new Badge('/^\d+\\.x$/'), + new StrykerHtmlReportBuilder($this->metricsCalculatorMock, new ResultsCollector()), + StrykerConfig::forBadge('/^\d+\\.x$/'), $this->logger ); - $badgeLogger->log(); + $strykerLogger->log(); $this->assertSame( [ @@ -394,12 +399,12 @@ public function test_it_sends_report_when_everything_is_ok_with_our_key(): void 'TRAVIS_BRANCH' => 'master', ]); - putenv('INFECTION_BADGE_API_KEY=abc'); + putenv('INFECTION_DASHBOARD_API_KEY=abc'); - $this->badgeApiClientMock + $this->strykerDashboardClient ->expects($this->once()) ->method('sendReport') - ->with('github.com/a/b', 'master', 'abc', 33.3) + ->with('github.com/a/b', 'master', 'abc', '{"mutationScore":33.3}') ; $this->metricsCalculatorMock @@ -407,7 +412,53 @@ public function test_it_sends_report_when_everything_is_ok_with_our_key(): void ->willReturn(33.3) ; - $this->badgeLogger->log(); + $this->strykerLogger->log(); + + $this->assertSame( + [ + [ + LogLevel::WARNING, + 'Sending dashboard report...', + [], + ], + ], + $this->logger->getLogs() + ); + } + + public function test_it_sends_report_when_everything_is_ok_with_our_key_for_full_report(): void + { + $this->strykerLogger = new StrykerLogger( + new BuildContextResolver(CiDetector::fromEnvironment($this->ciDetectorEnv)), + new StrykerApiKeyResolver(), + $this->strykerDashboardClient, + $this->metricsCalculatorMock, + new StrykerHtmlReportBuilder($this->metricsCalculatorMock, new ResultsCollector()), + StrykerConfig::forFullReport('master'), + $this->logger + ); + + $this->ciDetectorEnv->setVariables([ + 'TRAVIS' => 'true', + 'TRAVIS_PULL_REQUEST' => 'false', + 'TRAVIS_REPO_SLUG' => 'a/b', + 'TRAVIS_BRANCH' => 'master', + ]); + + putenv('INFECTION_DASHBOARD_API_KEY=abc'); + + $this->strykerDashboardClient + ->expects($this->once()) + ->method('sendReport') + ->with('github.com/a/b', 'master', 'abc', '{"schemaVersion":"1","thresholds":{"high":90,"low":50},"files":{},"testFiles":{},"framework":{"name":"Infection","branding":{"homepageUrl":"https:\/\/infection.github.io\/","imageUrl":"https:\/\/infection.github.io\/images\/logo.png"}}}') + ; + + $this->metricsCalculatorMock + ->method('getMutationScoreIndicator') + ->willReturn(33.3) + ; + + $this->strykerLogger->log(); $this->assertSame( [