Skip to content

Commit 568db5c

Browse files
committed
[Tests] Added missing test coverage for JMS PHP file visitors
1 parent fd26276 commit 568db5c

7 files changed

+297
-74
lines changed
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
<?php
2+
3+
/**
4+
* @copyright Copyright (C) Ibexa AS. All rights reserved.
5+
* @license For full copyright and license information view LICENSE file distributed with this source code.
6+
*/
7+
declare(strict_types=1);
8+
9+
namespace Ibexa\Tests\Core\MVC\Symfony\Translation;
10+
11+
use Doctrine\Common\Annotations\DocParser;
12+
use JMS\TranslationBundle\Model\MessageCatalogue;
13+
use JMS\TranslationBundle\Translation\Extractor\FileVisitorInterface;
14+
use JMS\TranslationBundle\Translation\FileSourceFactory;
15+
use PhpParser\Parser;
16+
use PhpParser\ParserFactory;
17+
use PHPUnit\Framework\TestCase;
18+
use SplFileInfo;
19+
20+
abstract class BaseMessageExtractorPhpFileVisitorTestCase extends TestCase
21+
{
22+
protected const string FIXTURES_DIR = __DIR__ . '/fixtures/';
23+
24+
protected Parser $phpParser;
25+
26+
protected FileVisitorInterface $visitor;
27+
28+
/**
29+
* @return iterable<string, array{string, array<\JMS\TranslationBundle\Model\Message>}>
30+
*/
31+
abstract public static function getDataForTestExtractTranslation(): iterable;
32+
33+
abstract protected function buildVisitor(
34+
DocParser $docParser,
35+
FileSourceFactory $fileSourceFactory
36+
): FileVisitorInterface;
37+
38+
protected function setUp(): void
39+
{
40+
$docParser = new DocParser();
41+
$fileSourceFactory = new FileSourceFactory(self::FIXTURES_DIR);
42+
$factory = new ParserFactory();
43+
$this->phpParser = $factory->createForHostVersion();
44+
$this->visitor = $this->buildVisitor($docParser, $fileSourceFactory);
45+
}
46+
47+
/**
48+
* @dataProvider getDataForTestExtractTranslation
49+
*
50+
* @param array<\JMS\TranslationBundle\Model\Message> $expectedMessages
51+
*/
52+
public function testExtractTranslation(string $phpFileName, array $expectedMessages): void
53+
{
54+
$messageCatalogue = new MessageCatalogue();
55+
$file = self::FIXTURES_DIR . $phpFileName;
56+
$fileInfo = new SplFileInfo($file);
57+
58+
$ast = $this->getASTFromFile($file);
59+
$this->visitor->visitPhpFile(
60+
$fileInfo,
61+
$messageCatalogue,
62+
$ast
63+
);
64+
65+
foreach ($expectedMessages as $expectedMessage) {
66+
self::assertTrue(
67+
$messageCatalogue->has($expectedMessage),
68+
'Message catalogue does not have the expected message: ' . var_export($expectedMessage, true) . PHP_EOL
69+
. 'Current message catalogue structure: ' . var_export($messageCatalogue, true)
70+
);
71+
}
72+
}
73+
74+
public function testNoTranslationToExtract(): void
75+
{
76+
$messageCatalogue = new MessageCatalogue();
77+
$file = self::FIXTURES_DIR . 'NoTranslationToExtract.php';
78+
$fileInfo = new SplFileInfo($file);
79+
80+
$ast = $this->getASTFromFile($file);
81+
$this->visitor->visitPhpFile(
82+
$fileInfo,
83+
$messageCatalogue,
84+
$ast
85+
);
86+
87+
self::assertEmpty($messageCatalogue->getDomains());
88+
}
89+
90+
/**
91+
* @return \PhpParser\Node\Stmt[]
92+
*/
93+
protected function getASTFromFile(string $filePath): array
94+
{
95+
$fileContents = file_get_contents($filePath);
96+
assert($fileContents !== false, "Failed to read $filePath");
97+
98+
$ast = $this->phpParser->parse($fileContents);
99+
assert($ast !== null, "Failed to parse AST of $filePath");
100+
101+
return $ast;
102+
}
103+
}

tests/lib/MVC/Symfony/Translation/ExceptionMessageTemplateFileVisitorTest.php

Lines changed: 27 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -10,71 +10,27 @@
1010

1111
use Doctrine\Common\Annotations\DocParser;
1212
use Ibexa\Core\MVC\Symfony\Translation\ExceptionMessageTemplateFileVisitor;
13+
use JMS\TranslationBundle\Logger\LoggerAwareInterface;
1314
use JMS\TranslationBundle\Model\Message;
1415
use JMS\TranslationBundle\Model\MessageCatalogue;
16+
use JMS\TranslationBundle\Translation\Extractor\FileVisitorInterface;
1517
use JMS\TranslationBundle\Translation\FileSourceFactory;
16-
use PhpParser\Parser;
17-
use PhpParser\ParserFactory;
18-
use PHPUnit\Framework\TestCase;
1918
use Psr\Log\LoggerInterface;
2019
use SplFileInfo;
2120

22-
final class ExceptionMessageTemplateFileVisitorTest extends TestCase
21+
/**
22+
* @covers \Ibexa\Core\MVC\Symfony\Translation\ExceptionMessageTemplateFileVisitor
23+
*/
24+
final class ExceptionMessageTemplateFileVisitorTest extends BaseMessageExtractorPhpFileVisitorTestCase
2325
{
24-
private const string FIXTURES_DIR = __DIR__ . '/fixtures/';
25-
26-
private Parser $phpParser;
27-
28-
private ExceptionMessageTemplateFileVisitor $exceptionMessageTemplateFileVisitor;
29-
30-
protected function setUp(): void
26+
public static function getDataForTestExtractTranslation(): iterable
3127
{
32-
$docParser = new DocParser();
33-
$fileSourceFactory = new FileSourceFactory(
34-
self::FIXTURES_DIR,
35-
);
36-
$factory = new ParserFactory();
37-
$this->phpParser = $factory->createForHostVersion();
38-
$this->exceptionMessageTemplateFileVisitor = new ExceptionMessageTemplateFileVisitor(
39-
$docParser,
40-
$fileSourceFactory
41-
);
42-
}
43-
44-
public function testExtractTranslation(): void
45-
{
46-
$messageCatalogue = new MessageCatalogue();
47-
$file = self::FIXTURES_DIR . 'SetMessageTemplate.php';
48-
$fileInfo = new SplFileInfo($file);
49-
50-
$ast = $this->getASTFromFile($file);
51-
$this->exceptionMessageTemplateFileVisitor->visitPhpFile(
52-
$fileInfo,
53-
$messageCatalogue,
54-
$ast
55-
);
56-
57-
$expectedMessage = new Message('Foo exception', 'ibexa_repository_exceptions');
58-
59-
self::assertTrue(
60-
$messageCatalogue->has($expectedMessage)
61-
);
62-
}
63-
64-
public function testNoTranslationToExtract(): void
65-
{
66-
$messageCatalogue = new MessageCatalogue();
67-
$file = self::FIXTURES_DIR . 'NoTranslationToExtract.php';
68-
$fileInfo = new SplFileInfo($file);
69-
70-
$ast = $this->getASTFromFile($file);
71-
$this->exceptionMessageTemplateFileVisitor->visitPhpFile(
72-
$fileInfo,
73-
$messageCatalogue,
74-
$ast
75-
);
76-
77-
self::assertEmpty($messageCatalogue->getDomains());
28+
yield 'TranslatableBase::setMessageTemplate()' => [
29+
'SetMessageTemplate.php',
30+
[
31+
new Message('Foo exception', 'ibexa_repository_exceptions'),
32+
],
33+
];
7834
}
7935

8036
public function testWrongTranslationId(): void
@@ -85,30 +41,27 @@ public function testWrongTranslationId(): void
8541

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

88-
$logger = $this->createMock(LoggerInterface::class);
89-
$logger
90-
->expects(self::once())
91-
->method('error');
44+
if ($this->visitor instanceof LoggerAwareInterface) {
45+
$logger = $this->createMock(LoggerInterface::class);
46+
$logger
47+
->expects(self::once())
48+
->method('error');
49+
50+
$this->visitor->setLogger($logger);
51+
}
9252

93-
$this->exceptionMessageTemplateFileVisitor->setLogger($logger);
94-
$this->exceptionMessageTemplateFileVisitor->visitPhpFile(
53+
$this->visitor->visitPhpFile(
9554
$fileInfo,
9655
$messageCatalogue,
9756
$ast
9857
);
9958
}
10059

101-
/**
102-
* @return \PhpParser\Node\Stmt[]
103-
*/
104-
private function getASTFromFile(string $filePath): array
60+
protected function buildVisitor(DocParser $docParser, FileSourceFactory $fileSourceFactory): FileVisitorInterface
10561
{
106-
$fileContents = file_get_contents($filePath);
107-
assert($fileContents !== false, "Failed to read $filePath");
108-
109-
$ast = $this->phpParser->parse($fileContents);
110-
assert($ast !== null, "Failed to parse AST of $filePath");
111-
112-
return $ast;
62+
return new ExceptionMessageTemplateFileVisitor(
63+
$docParser,
64+
$fileSourceFactory
65+
);
11366
}
11467
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
/**
4+
* @copyright Copyright (C) Ibexa AS. All rights reserved.
5+
* @license For full copyright and license information view LICENSE file distributed with this source code.
6+
*/
7+
declare(strict_types=1);
8+
9+
namespace Ibexa\Tests\Core\MVC\Symfony\Translation;
10+
11+
use Doctrine\Common\Annotations\DocParser;
12+
use Ibexa\Core\MVC\Symfony\Translation\TranslatableExceptionsFileVisitor;
13+
use JMS\TranslationBundle\Model\Message;
14+
use JMS\TranslationBundle\Translation\Extractor\FileVisitorInterface;
15+
use JMS\TranslationBundle\Translation\FileSourceFactory;
16+
17+
/**
18+
* @covers \Ibexa\Core\MVC\Symfony\Translation\TranslatableExceptionsFileVisitor
19+
*/
20+
final class TranslatableExceptionsFileVisitorTest extends BaseMessageExtractorPhpFileVisitorTestCase
21+
{
22+
public static function getDataForTestExtractTranslation(): iterable
23+
{
24+
yield 'throw new ContentValidationException()' => [
25+
'ContentValidationExceptionUsageStub.php',
26+
[
27+
new Message('Content with ID %contentId% could not be found', 'ibexa_repository_exceptions'),
28+
],
29+
];
30+
31+
yield 'throw new ForbiddenException()' => [
32+
'ForbiddenExceptionUsageStub.php',
33+
[
34+
new Message('Forbidden exception', 'ibexa_repository_exceptions'),
35+
],
36+
];
37+
}
38+
39+
protected function buildVisitor(DocParser $docParser, FileSourceFactory $fileSourceFactory): FileVisitorInterface
40+
{
41+
return new TranslatableExceptionsFileVisitor($docParser, $fileSourceFactory);
42+
}
43+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
/**
4+
* @copyright Copyright (C) Ibexa AS. All rights reserved.
5+
* @license For full copyright and license information view LICENSE file distributed with this source code.
6+
*/
7+
declare(strict_types=1);
8+
9+
namespace Ibexa\Tests\Core\MVC\Symfony\Translation;
10+
11+
use Doctrine\Common\Annotations\DocParser;
12+
use Ibexa\Core\MVC\Symfony\Translation\ValidationErrorFileVisitor;
13+
use JMS\TranslationBundle\Model\Message;
14+
use JMS\TranslationBundle\Translation\Extractor\FileVisitorInterface;
15+
use JMS\TranslationBundle\Translation\FileSourceFactory;
16+
17+
/**
18+
* @covers \Ibexa\Core\MVC\Symfony\Translation\ValidationErrorFileVisitor
19+
*/
20+
final class ValidationErrorFileVisitorTest extends BaseMessageExtractorPhpFileVisitorTestCase
21+
{
22+
/**
23+
* @return iterable<string, array{string, array<\JMS\TranslationBundle\Model\Message>}>
24+
*/
25+
public static function getDataForTestExtractTranslation(): iterable
26+
{
27+
yield 'new ValidationError()' => [
28+
'ValidationErrorUsageStub.php',
29+
[
30+
new Message('error_1.singular_only', 'ibexa_repository_exceptions'),
31+
new Message('error_2.singular', 'ibexa_repository_exceptions'),
32+
new Message('error_2.plural', 'ibexa_repository_exceptions'),
33+
],
34+
];
35+
}
36+
37+
protected function buildVisitor(DocParser $docParser, FileSourceFactory $fileSourceFactory): FileVisitorInterface
38+
{
39+
return new ValidationErrorFileVisitor(
40+
$docParser,
41+
$fileSourceFactory
42+
);
43+
}
44+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
/**
4+
* @copyright Copyright (C) Ibexa AS. All rights reserved.
5+
* @license For full copyright and license information view LICENSE file distributed with this source code.
6+
*/
7+
declare(strict_types=1);
8+
9+
namespace Ibexa\Tests\Core\MVC\Symfony\Translation\fixtures;
10+
11+
use Ibexa\Core\Base\Exceptions\ContentValidationException;
12+
13+
/**
14+
* @see \Ibexa\Tests\Core\MVC\Symfony\Translation\TranslatableExceptionsFileVisitorTest
15+
*/
16+
final class ContentValidationExceptionUsageStub
17+
{
18+
/**
19+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\ContentValidationException
20+
*/
21+
public function foo(): void
22+
{
23+
throw new ContentValidationException(
24+
'Content with ID %contentId% could not be found',
25+
['%contentId%' => 123]
26+
);
27+
}
28+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
/**
4+
* @copyright Copyright (C) Ibexa AS. All rights reserved.
5+
* @license For full copyright and license information view LICENSE file distributed with this source code.
6+
*/
7+
declare(strict_types=1);
8+
9+
namespace Ibexa\Tests\Core\MVC\Symfony\Translation\fixtures;
10+
11+
use Ibexa\Core\Base\Exceptions\ForbiddenException;
12+
13+
/**
14+
* @see \Ibexa\Tests\Core\MVC\Symfony\Translation\TranslatableExceptionsFileVisitorTest
15+
*/
16+
final class ForbiddenExceptionUsageStub
17+
{
18+
/**
19+
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\ForbiddenException
20+
*/
21+
public function foo(): void
22+
{
23+
throw new ForbiddenException('Forbidden exception');
24+
}
25+
}

0 commit comments

Comments
 (0)