Skip to content

Commit

Permalink
Merge pull request #829 from Nyholm/json-formatter
Browse files Browse the repository at this point in the history
Add support for JsonFormatter
  • Loading branch information
Ocramius authored Oct 8, 2024
2 parents d0ba4f1 + 7e92f54 commit 42af3cd
Show file tree
Hide file tree
Showing 6 changed files with 332 additions and 2 deletions.
66 changes: 66 additions & 0 deletions Resources/errors.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://github.com/Roave/BackwardCompatibilityCheck/tree/8.10.x/Resources/errors.schema.json",
"title": "Backward Compatibility Errors",
"description": "A list of errors",
"required": [
"errors"
],
"additionalProperties": false,
"properties": {
"errors": {
"type": "array",
"items": {
"$ref": "#/definitions/Error"
}
}
},
"definitions": {
"Error": {
"type": "object",
"additionalProperties": false,
"properties": {
"description": {
"type": "string"
},
"path": {
"anyOf": [
{
"type": "null"
},
{
"type": "string"
}
]
},
"line": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
]
},
"column": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
]
}
},
"required": [
"column",
"description",
"line",
"path"
],
"title": "Error"
}
}
}
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
],
"require-dev": {
"doctrine/coding-standard": "^12.0.0",
"estahn/phpunit-json-assertions": "^4.0",
"php-standard-library/psalm-plugin": "^2.3.0",
"phpunit/phpunit": "^9.6.19",
"psalm/plugin-phpunit": "^0.19.0",
Expand Down
130 changes: 128 additions & 2 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions src/Command/AssertBackwardsCompatible.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Roave\BackwardCompatibility\CompareApi;
use Roave\BackwardCompatibility\Factory\ComposerInstallationReflectorFactory;
use Roave\BackwardCompatibility\Formatter\GithubActionsFormatter;
use Roave\BackwardCompatibility\Formatter\JsonFormatter;
use Roave\BackwardCompatibility\Formatter\JunitFormatter;
use Roave\BackwardCompatibility\Formatter\MarkdownPipedToSymfonyConsoleFormatter;
use Roave\BackwardCompatibility\Formatter\SymfonyConsoleTextFormatter;
Expand Down Expand Up @@ -154,6 +155,7 @@ public function execute(InputInterface $input, OutputInterface $output): int
'console' => new SymfonyConsoleTextFormatter($stdErr),
'markdown' => new MarkdownPipedToSymfonyConsoleFormatter($output),
'github-actions' => new GithubActionsFormatter($output, $toPath),
'json' => new JsonFormatter($output, $toPath),
'junit' => new JunitFormatter($output, $toPath),
];

Expand All @@ -162,6 +164,7 @@ public function execute(InputInterface $input, OutputInterface $output): int
Type\literal_scalar('console'),
Type\literal_scalar('markdown'),
Type\literal_scalar('github-actions'),
Type\literal_scalar('json'),
Type\literal_scalar('junit'),
))->coerce((array) $input->getOption('format')) as $format
) {
Expand Down
39 changes: 39 additions & 0 deletions src/Formatter/JsonFormatter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

declare(strict_types=1);

namespace Roave\BackwardCompatibility\Formatter;

use Psl\Str;
use Roave\BackwardCompatibility\Changes;
use Roave\BackwardCompatibility\Git\CheckedOutRepository;
use Symfony\Component\Console\Output\OutputInterface;

use function json_encode;

/** @internal */
final class JsonFormatter implements OutputFormatter
{
public function __construct(
private readonly OutputInterface $output,
private CheckedOutRepository $basePath,
) {
}

public function write(Changes $changes): void
{
$basePath = $this->basePath->__toString() . '/';
$result = [];

foreach ($changes as $change) {
$result[] = [
'description' => $change->description,
'path' => $change->file === null ? null : Str\replace($change->file, $basePath, ''),
'line' => $change->line,
'column' => $change->column,
];
}

$this->output->writeln(json_encode(['errors' => $result]));
}
}
95 changes: 95 additions & 0 deletions test/unit/Formatter/JsonFormatterTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<?php

declare(strict_types=1);

namespace RoaveTest\BackwardCompatibility\Formatter;

use EnricoStahn\JsonAssert\AssertClass as JsonAssert;
use PHPUnit\Framework\TestCase;
use Psl\Env;
use Psl\Filesystem;
use ReflectionException;
use Roave\BackwardCompatibility\Change;
use Roave\BackwardCompatibility\Changes;
use Roave\BackwardCompatibility\Formatter\JsonFormatter;
use Roave\BackwardCompatibility\Git\CheckedOutRepository;
use stdClass;
use Symfony\Component\Console\Output\BufferedOutput;

use function dirname;
use function json_decode;

use const JSON_THROW_ON_ERROR;

/** @covers \Roave\BackwardCompatibility\Formatter\JsonFormatter */
final class JsonFormatterTest extends TestCase
{
/** @throws ReflectionException */
public function testWrite(): void
{
$output = new BufferedOutput();
$temporaryLocation = Filesystem\create_temporary_file(Env\temp_dir(), 'jsonFormatter');

Filesystem\delete_file($temporaryLocation);
Filesystem\create_directory($temporaryLocation . '/foo/bar/.git');

(new JsonFormatter(
$output,
CheckedOutRepository::fromPath($temporaryLocation . '/foo/bar'),
))->write(Changes::fromList(
Change::removed('foo', true),
Change::added('bar', false),
Change::changed('baz', false)
->onFile('baz-file.php'),
Change::changed('tab', false)
->onFile('tab-file.php')
->onLine(5),
Change::changed('taz', false)
->onFile('taz-file.php')
->onLine(6)
->onColumn(15),
Change::changed('tar', false)
->onFile('tar-file.php')
->onLine(-1)
->onColumn(-1),
Change::changed('file-in-checked-out-dir', false)
->onFile($temporaryLocation . '/foo/bar/subpath/file-in-checked-out-dir.php')
->onLine(10)
->onColumn(20),
));

Filesystem\delete_directory($temporaryLocation, true);

$expected = [
'errors' => [
['description' => 'foo', 'path' => null, 'line' => null, 'column' => null],
['description' => 'bar', 'path' => null, 'line' => null, 'column' => null],
['description' => 'baz', 'path' => 'baz-file.php', 'line' => null, 'column' => null],
['description' => 'tab', 'path' => 'tab-file.php', 'line' => 5, 'column' => null],
['description' => 'taz', 'path' => 'taz-file.php', 'line' => 6, 'column' => 15],
['description' => 'tar', 'path' => 'tar-file.php', 'line' => -1, 'column' => -1],
['description' => 'file-in-checked-out-dir', 'path' => 'subpath/file-in-checked-out-dir.php', 'line' => 10, 'column' => 20],
],
];

$json = $output->fetch();
self::assertJson($json);

$data = json_decode($json, true);
self::assertIsArray($data);
self::assertEquals($expected, $data);

$content = json_decode($json, flags: JSON_THROW_ON_ERROR);
self::assertInstanceOf(stdClass::class, $content);
JsonAssert::assertJsonMatchesSchema($content, dirname(__DIR__, 3) . '/Resources/errors.schema.json');

self::assertJsonStringEqualsJsonString(
<<<'OUTPUT'
{"errors":[{"description":"foo","path":null,"line":null,"column":null},{"description":"bar","path":null,"line":null,"column":null},{"description":"baz","path":"baz-file.php","line":null,"column":null},{"description":"tab","path":"tab-file.php","line":5,"column":null},{"description":"taz","path":"taz-file.php","line":6,"column":15},{"description":"tar","path":"tar-file.php","line":-1,"column":-1},{"description":"file-in-checked-out-dir","path":"subpath\/file-in-checked-out-dir.php","line":10,"column":20}]}

OUTPUT
,
$json,
);
}
}

0 comments on commit 42af3cd

Please sign in to comment.