Skip to content

Commit

Permalink
[Tests] Added missing test coverage for JMS PHP file visitors
Browse files Browse the repository at this point in the history
  • Loading branch information
alongosz committed Oct 30, 2024
1 parent fd26276 commit 568db5c
Show file tree
Hide file tree
Showing 7 changed files with 297 additions and 74 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\Tests\Core\MVC\Symfony\Translation;

use Doctrine\Common\Annotations\DocParser;
use JMS\TranslationBundle\Model\MessageCatalogue;
use JMS\TranslationBundle\Translation\Extractor\FileVisitorInterface;
use JMS\TranslationBundle\Translation\FileSourceFactory;
use PhpParser\Parser;
use PhpParser\ParserFactory;
use PHPUnit\Framework\TestCase;
use SplFileInfo;

abstract class BaseMessageExtractorPhpFileVisitorTestCase extends TestCase
{
protected const string FIXTURES_DIR = __DIR__ . '/fixtures/';

protected Parser $phpParser;

protected FileVisitorInterface $visitor;

/**
* @return iterable<string, array{string, array<\JMS\TranslationBundle\Model\Message>}>
*/
abstract public static function getDataForTestExtractTranslation(): iterable;

abstract protected function buildVisitor(
DocParser $docParser,
FileSourceFactory $fileSourceFactory
): FileVisitorInterface;

protected function setUp(): void
{
$docParser = new DocParser();
$fileSourceFactory = new FileSourceFactory(self::FIXTURES_DIR);
$factory = new ParserFactory();
$this->phpParser = $factory->createForHostVersion();
$this->visitor = $this->buildVisitor($docParser, $fileSourceFactory);
}

/**
* @dataProvider getDataForTestExtractTranslation
*
* @param array<\JMS\TranslationBundle\Model\Message> $expectedMessages
*/
public function testExtractTranslation(string $phpFileName, array $expectedMessages): void
{
$messageCatalogue = new MessageCatalogue();
$file = self::FIXTURES_DIR . $phpFileName;
$fileInfo = new SplFileInfo($file);

$ast = $this->getASTFromFile($file);
$this->visitor->visitPhpFile(
$fileInfo,
$messageCatalogue,
$ast
);

foreach ($expectedMessages as $expectedMessage) {
self::assertTrue(
$messageCatalogue->has($expectedMessage),
'Message catalogue does not have the expected message: ' . var_export($expectedMessage, true) . PHP_EOL
. 'Current message catalogue structure: ' . var_export($messageCatalogue, true)
);
}
}

public function testNoTranslationToExtract(): void
{
$messageCatalogue = new MessageCatalogue();
$file = self::FIXTURES_DIR . 'NoTranslationToExtract.php';
$fileInfo = new SplFileInfo($file);

$ast = $this->getASTFromFile($file);
$this->visitor->visitPhpFile(
$fileInfo,
$messageCatalogue,
$ast
);

self::assertEmpty($messageCatalogue->getDomains());
}

/**
* @return \PhpParser\Node\Stmt[]
*/
protected function getASTFromFile(string $filePath): array
{
$fileContents = file_get_contents($filePath);
assert($fileContents !== false, "Failed to read $filePath");

$ast = $this->phpParser->parse($fileContents);
assert($ast !== null, "Failed to parse AST of $filePath");

return $ast;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,71 +10,27 @@

use Doctrine\Common\Annotations\DocParser;
use Ibexa\Core\MVC\Symfony\Translation\ExceptionMessageTemplateFileVisitor;
use JMS\TranslationBundle\Logger\LoggerAwareInterface;
use JMS\TranslationBundle\Model\Message;
use JMS\TranslationBundle\Model\MessageCatalogue;
use JMS\TranslationBundle\Translation\Extractor\FileVisitorInterface;
use JMS\TranslationBundle\Translation\FileSourceFactory;
use PhpParser\Parser;
use PhpParser\ParserFactory;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
use SplFileInfo;

final class ExceptionMessageTemplateFileVisitorTest extends TestCase
/**
* @covers \Ibexa\Core\MVC\Symfony\Translation\ExceptionMessageTemplateFileVisitor
*/
final class ExceptionMessageTemplateFileVisitorTest extends BaseMessageExtractorPhpFileVisitorTestCase
{
private const string FIXTURES_DIR = __DIR__ . '/fixtures/';

private Parser $phpParser;

private ExceptionMessageTemplateFileVisitor $exceptionMessageTemplateFileVisitor;

protected function setUp(): void
public static function getDataForTestExtractTranslation(): iterable
{
$docParser = new DocParser();
$fileSourceFactory = new FileSourceFactory(
self::FIXTURES_DIR,
);
$factory = new ParserFactory();
$this->phpParser = $factory->createForHostVersion();
$this->exceptionMessageTemplateFileVisitor = new ExceptionMessageTemplateFileVisitor(
$docParser,
$fileSourceFactory
);
}

public function testExtractTranslation(): void
{
$messageCatalogue = new MessageCatalogue();
$file = self::FIXTURES_DIR . 'SetMessageTemplate.php';
$fileInfo = new SplFileInfo($file);

$ast = $this->getASTFromFile($file);
$this->exceptionMessageTemplateFileVisitor->visitPhpFile(
$fileInfo,
$messageCatalogue,
$ast
);

$expectedMessage = new Message('Foo exception', 'ibexa_repository_exceptions');

self::assertTrue(
$messageCatalogue->has($expectedMessage)
);
}

public function testNoTranslationToExtract(): void
{
$messageCatalogue = new MessageCatalogue();
$file = self::FIXTURES_DIR . 'NoTranslationToExtract.php';
$fileInfo = new SplFileInfo($file);

$ast = $this->getASTFromFile($file);
$this->exceptionMessageTemplateFileVisitor->visitPhpFile(
$fileInfo,
$messageCatalogue,
$ast
);

self::assertEmpty($messageCatalogue->getDomains());
yield 'TranslatableBase::setMessageTemplate()' => [
'SetMessageTemplate.php',
[
new Message('Foo exception', 'ibexa_repository_exceptions'),
],
];
}

public function testWrongTranslationId(): void
Expand All @@ -85,30 +41,27 @@ public function testWrongTranslationId(): void

$ast = $this->getASTFromFile($file);

$logger = $this->createMock(LoggerInterface::class);
$logger
->expects(self::once())
->method('error');
if ($this->visitor instanceof LoggerAwareInterface) {
$logger = $this->createMock(LoggerInterface::class);
$logger
->expects(self::once())
->method('error');

$this->visitor->setLogger($logger);
}

$this->exceptionMessageTemplateFileVisitor->setLogger($logger);
$this->exceptionMessageTemplateFileVisitor->visitPhpFile(
$this->visitor->visitPhpFile(
$fileInfo,
$messageCatalogue,
$ast
);
}

/**
* @return \PhpParser\Node\Stmt[]
*/
private function getASTFromFile(string $filePath): array
protected function buildVisitor(DocParser $docParser, FileSourceFactory $fileSourceFactory): FileVisitorInterface
{
$fileContents = file_get_contents($filePath);
assert($fileContents !== false, "Failed to read $filePath");

$ast = $this->phpParser->parse($fileContents);
assert($ast !== null, "Failed to parse AST of $filePath");

return $ast;
return new ExceptionMessageTemplateFileVisitor(
$docParser,
$fileSourceFactory
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\Tests\Core\MVC\Symfony\Translation;

use Doctrine\Common\Annotations\DocParser;
use Ibexa\Core\MVC\Symfony\Translation\TranslatableExceptionsFileVisitor;
use JMS\TranslationBundle\Model\Message;
use JMS\TranslationBundle\Translation\Extractor\FileVisitorInterface;
use JMS\TranslationBundle\Translation\FileSourceFactory;

/**
* @covers \Ibexa\Core\MVC\Symfony\Translation\TranslatableExceptionsFileVisitor
*/
final class TranslatableExceptionsFileVisitorTest extends BaseMessageExtractorPhpFileVisitorTestCase
{
public static function getDataForTestExtractTranslation(): iterable
{
yield 'throw new ContentValidationException()' => [
'ContentValidationExceptionUsageStub.php',
[
new Message('Content with ID %contentId% could not be found', 'ibexa_repository_exceptions'),
],
];

yield 'throw new ForbiddenException()' => [
'ForbiddenExceptionUsageStub.php',
[
new Message('Forbidden exception', 'ibexa_repository_exceptions'),
],
];
}

protected function buildVisitor(DocParser $docParser, FileSourceFactory $fileSourceFactory): FileVisitorInterface
{
return new TranslatableExceptionsFileVisitor($docParser, $fileSourceFactory);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\Tests\Core\MVC\Symfony\Translation;

use Doctrine\Common\Annotations\DocParser;
use Ibexa\Core\MVC\Symfony\Translation\ValidationErrorFileVisitor;
use JMS\TranslationBundle\Model\Message;
use JMS\TranslationBundle\Translation\Extractor\FileVisitorInterface;
use JMS\TranslationBundle\Translation\FileSourceFactory;

/**
* @covers \Ibexa\Core\MVC\Symfony\Translation\ValidationErrorFileVisitor
*/
final class ValidationErrorFileVisitorTest extends BaseMessageExtractorPhpFileVisitorTestCase
{
/**
* @return iterable<string, array{string, array<\JMS\TranslationBundle\Model\Message>}>
*/
public static function getDataForTestExtractTranslation(): iterable
{
yield 'new ValidationError()' => [
'ValidationErrorUsageStub.php',
[
new Message('error_1.singular_only', 'ibexa_repository_exceptions'),
new Message('error_2.singular', 'ibexa_repository_exceptions'),
new Message('error_2.plural', 'ibexa_repository_exceptions'),
],
];
}

protected function buildVisitor(DocParser $docParser, FileSourceFactory $fileSourceFactory): FileVisitorInterface
{
return new ValidationErrorFileVisitor(
$docParser,
$fileSourceFactory
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\Tests\Core\MVC\Symfony\Translation\fixtures;

use Ibexa\Core\Base\Exceptions\ContentValidationException;

/**
* @see \Ibexa\Tests\Core\MVC\Symfony\Translation\TranslatableExceptionsFileVisitorTest
*/
final class ContentValidationExceptionUsageStub
{
/**
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentValidationException
*/
public function foo(): void
{
throw new ContentValidationException(
'Content with ID %contentId% could not be found',
['%contentId%' => 123]
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\Tests\Core\MVC\Symfony\Translation\fixtures;

use Ibexa\Core\Base\Exceptions\ForbiddenException;

/**
* @see \Ibexa\Tests\Core\MVC\Symfony\Translation\TranslatableExceptionsFileVisitorTest
*/
final class ForbiddenExceptionUsageStub
{
/**
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\ForbiddenException
*/
public function foo(): void
{
throw new ForbiddenException('Forbidden exception');
}
}
Loading

0 comments on commit 568db5c

Please sign in to comment.