Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[Translation] Rework PhpAstExtractor tests organization for future improvements #60854

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

Open
wants to merge 1 commit into
base: 7.4
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ protected function addMessageToCatalogue(string $message, ?string $domain, int $
$domain ??= 'messages';
$this->catalogue->set($message, $this->messagePrefix.$message, $domain);
$metadata = $this->catalogue->getMetadata($message, $domain) ?? [];
$normalizedFilename = preg_replace('{[\\\\/]+}', '/', $this->file);
$metadata['sources'][] = $normalizedFilename.':'.$line;
$metadata['sources'][] = $this->file->getPathname().':'.$line;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this was done so that extracted metadata always use / in paths even when running on Windows (avoiding to change the metadata depending on whether the last dev running the extraction was using Windows or Unix)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

however, this would make sense only if the path was relative to the project root though. Otherwise, the project location on disk also affects the metadata.

In any case, this is a user-visible change that should probably not be hidden in a PR saying it reorganize tests. It might impact projects using those metadata.

$this->catalogue->setMetadata($message, $metadata, $domain);
}

Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace Symfony\Component\Translation\Tests\Extractor\Visitor;

use PhpParser\NodeVisitor;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Translation\Extractor\PhpAstExtractor;
use Symfony\Component\Translation\MessageCatalogue;

abstract class AbstractVisitorTest extends TestCase
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be named AbstractVisitorTestCase as PHPUnit 10 has deprecated the fact of having abstract classes matching the class name suffix of tests (which is Test by default, and we use the default), and PHPUnit 11 fails for such case.

{
abstract public function getVisitor(): NodeVisitor;
abstract public function getResource(): iterable|string;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should have pphdoc for 2 reasons:

  • document the return type fully
  • explain what this method is about

abstract public function assertCatalogue(MessageCatalogue $catalogue): void;

public function testVisitor()
{
$extractor = new PhpAstExtractor([$this->getVisitor()]);
$extractor->setPrefix('prefix');
$catalogue = new MessageCatalogue('en');

$extractor->extract($this->getResource(), $catalogue);

$this->assertCatalogue($catalogue);

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

namespace Symfony\Component\Translation\Tests\Extractor\Visitor;

use PhpParser\NodeVisitor;
use Symfony\Component\Translation\Extractor\Visitor\ConstraintVisitor;
use Symfony\Component\Translation\MessageCatalogue;

class ConstraintVisitorTest extends AbstractVisitorTest
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

having to make a new test class for each test looks weird to me.

we might want to have multiple tests running for ConstraintVisitor for instance, which would then require finding names for those test classes (instead of naming test methods like usual) or to merge everything in a single test (which removes any explanation of the intent of the test, and also prevents testing some legacy feature and non-legacy ones separately)

Designing the AbstractVisitorTest testcase in a way supporting a single test does not really matches the common PHPUnit architecture.
You should rather make it define a utility method taking a NodeVisitor and a resource as argument and returning a MessageCatalogue, and let each test class write as many tests it wants using this utility.

{
private const FIXTURES_FOLDER = __DIR__ . '/../../Fixtures/extractor-php-ast/constraint-visitor/';

public function getVisitor(): NodeVisitor
{
return new ConstraintVisitor(['NotBlank', 'Isbn', 'Length']);
}

public function getResource(): iterable|string
{
return self::FIXTURES_FOLDER;
}

public function assertCatalogue(MessageCatalogue $catalogue): void
{
$this->assertEquals(
[
'validators' => [
'message-in-constraint-attribute' => 'prefixmessage-in-constraint-attribute',
// 'custom Isbn message from attribute' => 'prefixcustom Isbn message from attribute',
'custom Isbn message from attribute with options as array' => 'prefixcustom Isbn message from attribute with options as array',
'custom Length exact message from attribute from named argument' => 'prefixcustom Length exact message from attribute from named argument',
'custom Length exact message from attribute from named argument 1/2' => 'prefixcustom Length exact message from attribute from named argument 1/2',
'custom Length min message from attribute from named argument 2/2' => 'prefixcustom Length min message from attribute from named argument 2/2',
// 'custom Isbn message' => 'prefixcustom Isbn message',
'custom Isbn message with options as array' => 'prefixcustom Isbn message with options as array',
'custom Isbn message from named argument' => 'prefixcustom Isbn message from named argument',
'custom Length exact message from named argument' => 'prefixcustom Length exact message from named argument',
'custom Length exact message from named argument 1/2' => 'prefixcustom Length exact message from named argument 1/2',
'custom Length min message from named argument 2/2' => 'prefixcustom Length min message from named argument 2/2',
],
],
$catalogue->all(),
);

$this->assertEquals(['sources' => [self::FIXTURES_FOLDER . 'validator-constraints.php:8']], $catalogue->getMetadata('message-in-constraint-attribute', 'validators'));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
<?php

namespace Symfony\Component\Translation\Tests\Extractor\Visitor;

use PhpParser\NodeVisitor;
use Symfony\Component\Translation\Extractor\Visitor\TransMethodVisitor;
use Symfony\Component\Translation\MessageCatalogue;

class TransMethodVisitorTest extends AbstractVisitorTest
{
private const FIXTURES_FOLDER = __DIR__ . '/../../Fixtures/extractor-php-ast/trans-method-visitor/';
public const OTHER_DOMAIN = 'not_messages';

public function getVisitor(): NodeVisitor
{
return new TransMethodVisitor();
}

public function getResource(): iterable|string
{
return self::FIXTURES_FOLDER;
}

public function assertCatalogue(MessageCatalogue $catalogue): void
{
$expectedHeredoc = <<<EOF
heredoc key with whitespace and escaped \$\n sequences
EOF;
$expectedNowdoc = <<<'EOF'
nowdoc key with whitespace and nonescaped \$\n sequences
EOF;

$this->assertEquals(
[
'messages' => [
'single-quoted key' => 'prefixsingle-quoted key',
'double-quoted key' => 'prefixdouble-quoted key',
'heredoc key' => 'prefixheredoc key',
'nowdoc key' => 'prefixnowdoc key',
"double-quoted key with whitespace and escaped \$\n\" sequences" => "prefixdouble-quoted key with whitespace and escaped \$\n\" sequences",
'single-quoted key with whitespace and nonescaped \\$\\n\' sequences' => 'prefixsingle-quoted key with whitespace and nonescaped \\$\\n\' sequences',
$expectedHeredoc => 'prefix'.$expectedHeredoc,
$expectedNowdoc => 'prefix'.$expectedNowdoc,
'single-quoted key with "quote mark at the end"' => 'prefixsingle-quoted key with "quote mark at the end"',
'concatenated message with heredoc and nowdoc' => 'prefixconcatenated message with heredoc and nowdoc',
'default domain' => 'prefixdefault domain',
'mix-named-arguments' => 'prefixmix-named-arguments',
'mix-named-arguments-locale' => 'prefixmix-named-arguments-locale',
'mix-named-arguments-without-domain' => 'prefixmix-named-arguments-without-domain',
"heredoc\nindented\n further" => "prefixheredoc\nindented\n further",
"nowdoc\nindented\n further" => "prefixnowdoc\nindented\n further",
'translatable-short single-quoted key' => 'prefixtranslatable-short single-quoted key',
'translatable-short double-quoted key' => 'prefixtranslatable-short double-quoted key',
'translatable-short heredoc key' => 'prefixtranslatable-short heredoc key',
'translatable-short nowdoc key' => 'prefixtranslatable-short nowdoc key',
"translatable-short double-quoted key with whitespace and escaped \$\n\" sequences" => "prefixtranslatable-short double-quoted key with whitespace and escaped \$\n\" sequences",
'translatable-short single-quoted key with whitespace and nonescaped \$\n\' sequences' => 'prefixtranslatable-short single-quoted key with whitespace and nonescaped \$\n\' sequences',
'translatable-short single-quoted key with "quote mark at the end"' => 'prefixtranslatable-short single-quoted key with "quote mark at the end"',
'translatable-short '.$expectedHeredoc => 'prefixtranslatable-short '.$expectedHeredoc,
'translatable-short '.$expectedNowdoc => 'prefixtranslatable-short '.$expectedNowdoc,
'translatable-short concatenated message with heredoc and nowdoc' => 'prefixtranslatable-short concatenated message with heredoc and nowdoc',
'translatable-short default domain' => 'prefixtranslatable-short default domain',
'translatable-short-fqn single-quoted key' => 'prefixtranslatable-short-fqn single-quoted key',
'translatable-short-fqn double-quoted key' => 'prefixtranslatable-short-fqn double-quoted key',
'translatable-short-fqn heredoc key' => 'prefixtranslatable-short-fqn heredoc key',
'translatable-short-fqn nowdoc key' => 'prefixtranslatable-short-fqn nowdoc key',
"translatable-short-fqn double-quoted key with whitespace and escaped \$\n\" sequences" => "prefixtranslatable-short-fqn double-quoted key with whitespace and escaped \$\n\" sequences",
'translatable-short-fqn single-quoted key with whitespace and nonescaped \$\n\' sequences' => 'prefixtranslatable-short-fqn single-quoted key with whitespace and nonescaped \$\n\' sequences',
'translatable-short-fqn single-quoted key with "quote mark at the end"' => 'prefixtranslatable-short-fqn single-quoted key with "quote mark at the end"',
'translatable-short-fqn '.$expectedHeredoc => 'prefixtranslatable-short-fqn '.$expectedHeredoc,
'translatable-short-fqn '.$expectedNowdoc => 'prefixtranslatable-short-fqn '.$expectedNowdoc,
'translatable-short-fqn concatenated message with heredoc and nowdoc' => 'prefixtranslatable-short-fqn concatenated message with heredoc and nowdoc',
'translatable-short-fqn default domain' => 'prefixtranslatable-short-fqn default domain',
],
'not_messages' => [
'other-domain-test-no-params-short-array' => 'prefixother-domain-test-no-params-short-array',
'other-domain-test-no-params-long-array' => 'prefixother-domain-test-no-params-long-array',
'other-domain-test-params-short-array' => 'prefixother-domain-test-params-short-array',
'other-domain-test-params-long-array' => 'prefixother-domain-test-params-long-array',
'typecast' => 'prefixtypecast',
'ordered-named-arguments-in-trans-method' => 'prefixordered-named-arguments-in-trans-method',
'disordered-named-arguments-in-trans-method' => 'prefixdisordered-named-arguments-in-trans-method',
'variable-assignation-inlined-in-trans-method-call1' => 'prefixvariable-assignation-inlined-in-trans-method-call1',
'variable-assignation-inlined-in-trans-method-call2' => 'prefixvariable-assignation-inlined-in-trans-method-call2',
'variable-assignation-inlined-in-trans-method-call3' => 'prefixvariable-assignation-inlined-in-trans-method-call3',
'variable-assignation-inlined-with-named-arguments-in-trans-method' => 'prefixvariable-assignation-inlined-with-named-arguments-in-trans-method',
'mix-named-arguments-without-parameters' => 'prefixmix-named-arguments-without-parameters',
'mix-named-arguments-disordered' => 'prefixmix-named-arguments-disordered',
'const-domain' => 'prefixconst-domain',
'translatable-short other-domain-test-no-params-short-array' => 'prefixtranslatable-short other-domain-test-no-params-short-array',
'translatable-short other-domain-test-no-params-long-array' => 'prefixtranslatable-short other-domain-test-no-params-long-array',
'translatable-short other-domain-test-params-short-array' => 'prefixtranslatable-short other-domain-test-params-short-array',
'translatable-short other-domain-test-params-long-array' => 'prefixtranslatable-short other-domain-test-params-long-array',
'translatable-short typecast' => 'prefixtranslatable-short typecast',
'translatable-short-fqn other-domain-test-no-params-short-array' => 'prefixtranslatable-short-fqn other-domain-test-no-params-short-array',
'translatable-short-fqn other-domain-test-no-params-long-array' => 'prefixtranslatable-short-fqn other-domain-test-no-params-long-array',
'translatable-short-fqn other-domain-test-params-short-array' => 'prefixtranslatable-short-fqn other-domain-test-params-short-array',
'translatable-short-fqn other-domain-test-params-long-array' => 'prefixtranslatable-short-fqn other-domain-test-params-long-array',
'translatable-short-fqn typecast' => 'prefixtranslatable-short-fqn typecast',
],
],
$catalogue->all(),
);

$this->assertEquals(['sources' => [self::FIXTURES_FOLDER . 'translation.html.php:2']], $catalogue->getMetadata('single-quoted key'));
$this->assertEquals(['sources' => [self::FIXTURES_FOLDER . 'translation.html.php:37']], $catalogue->getMetadata('other-domain-test-no-params-short-array', 'not_messages'));
$this->assertEquals(['sources' => [self::FIXTURES_FOLDER . 'translation-73.html.php:8']], $catalogue->getMetadata("nowdoc\nindented\n further"));

$this->assertEquals(['sources' => [self::FIXTURES_FOLDER . 'translatable-short.html.php:2']], $catalogue->getMetadata('translatable-short single-quoted key'));
$this->assertEquals(['sources' => [self::FIXTURES_FOLDER . 'translatable-short.html.php:37']], $catalogue->getMetadata('translatable-short other-domain-test-no-params-short-array', 'not_messages'));

$this->assertEquals(['sources' => [self::FIXTURES_FOLDER . 'translatable-short-fqn.html.php:2']], $catalogue->getMetadata('translatable-short-fqn single-quoted key'));
$this->assertEquals(['sources' => [self::FIXTURES_FOLDER . 'translatable-short-fqn.html.php:37']], $catalogue->getMetadata('translatable-short-fqn other-domain-test-no-params-short-array', 'not_messages'));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php

namespace Symfony\Component\Translation\Tests\Extractor\Visitor;

use PhpParser\NodeVisitor;
use Symfony\Component\Translation\Extractor\Visitor\TranslatableMessageVisitor;
use Symfony\Component\Translation\Extractor\Visitor\TransMethodVisitor;
use Symfony\Component\Translation\MessageCatalogue;

class TranslatableMessageVisitorTest extends AbstractVisitorTest
{
private const FIXTURES_FOLDER = __DIR__ . '/../../Fixtures/extractor-php-ast/translatable-message-visitor/';

public function getVisitor(): NodeVisitor
{
return new TranslatableMessageVisitor();
}

public function getResource(): iterable|string
{
return self::FIXTURES_FOLDER;
}

public function assertCatalogue(MessageCatalogue $catalogue): void
{
$expectedHeredoc = <<<EOF
heredoc key with whitespace and escaped \$\n sequences
EOF;
$expectedNowdoc = <<<'EOF'
nowdoc key with whitespace and nonescaped \$\n sequences
EOF;

$this->assertEquals(
[
'messages' => [
'translatable single-quoted key' => 'prefixtranslatable single-quoted key',
'translatable double-quoted key' => 'prefixtranslatable double-quoted key',
'translatable heredoc key' => 'prefixtranslatable heredoc key',
'translatable nowdoc key' => 'prefixtranslatable nowdoc key',
"translatable double-quoted key with whitespace and escaped \$\n\" sequences" => "prefixtranslatable double-quoted key with whitespace and escaped \$\n\" sequences",
'translatable single-quoted key with whitespace and nonescaped \$\n\' sequences' => 'prefixtranslatable single-quoted key with whitespace and nonescaped \$\n\' sequences',
'translatable single-quoted key with "quote mark at the end"' => 'prefixtranslatable single-quoted key with "quote mark at the end"',
'translatable '.$expectedHeredoc => 'prefixtranslatable '.$expectedHeredoc,
'translatable '.$expectedNowdoc => 'prefixtranslatable '.$expectedNowdoc,
'translatable concatenated message with heredoc and nowdoc' => 'prefixtranslatable concatenated message with heredoc and nowdoc',
'translatable default domain' => 'prefixtranslatable default domain',
'translatable-fqn single-quoted key' => 'prefixtranslatable-fqn single-quoted key',
'translatable-fqn double-quoted key' => 'prefixtranslatable-fqn double-quoted key',
'translatable-fqn heredoc key' => 'prefixtranslatable-fqn heredoc key',
'translatable-fqn nowdoc key' => 'prefixtranslatable-fqn nowdoc key',
"translatable-fqn double-quoted key with whitespace and escaped \$\n\" sequences" => "prefixtranslatable-fqn double-quoted key with whitespace and escaped \$\n\" sequences",
'translatable-fqn single-quoted key with whitespace and nonescaped \$\n\' sequences' => 'prefixtranslatable-fqn single-quoted key with whitespace and nonescaped \$\n\' sequences',
'translatable-fqn single-quoted key with "quote mark at the end"' => 'prefixtranslatable-fqn single-quoted key with "quote mark at the end"',
'translatable-fqn '.$expectedHeredoc => 'prefixtranslatable-fqn '.$expectedHeredoc,
'translatable-fqn '.$expectedNowdoc => 'prefixtranslatable-fqn '.$expectedNowdoc,
'translatable-fqn concatenated message with heredoc and nowdoc' => 'prefixtranslatable-fqn concatenated message with heredoc and nowdoc',
'translatable-fqn default domain' => 'prefixtranslatable-fqn default domain',
],
'not_messages' => [
'translatable other-domain-test-no-params-short-array' => 'prefixtranslatable other-domain-test-no-params-short-array',
'translatable other-domain-test-no-params-long-array' => 'prefixtranslatable other-domain-test-no-params-long-array',
'translatable other-domain-test-params-short-array' => 'prefixtranslatable other-domain-test-params-short-array',
'translatable other-domain-test-params-long-array' => 'prefixtranslatable other-domain-test-params-long-array',
'translatable typecast' => 'prefixtranslatable typecast',
'translatable-fqn other-domain-test-no-params-short-array' => 'prefixtranslatable-fqn other-domain-test-no-params-short-array',
'translatable-fqn other-domain-test-no-params-long-array' => 'prefixtranslatable-fqn other-domain-test-no-params-long-array',
'translatable-fqn other-domain-test-params-short-array' => 'prefixtranslatable-fqn other-domain-test-params-short-array',
'translatable-fqn other-domain-test-params-long-array' => 'prefixtranslatable-fqn other-domain-test-params-long-array',
'translatable-fqn typecast' => 'prefixtranslatable-fqn typecast',
],
],
$catalogue->all(),
);

$this->assertEquals(['sources' => [self::FIXTURES_FOLDER . 'translatable.html.php:2']], $catalogue->getMetadata('translatable single-quoted key'));
$this->assertEquals(['sources' => [self::FIXTURES_FOLDER . 'translatable.html.php:37']], $catalogue->getMetadata('translatable other-domain-test-no-params-short-array', 'not_messages'));

$this->assertEquals(['sources' => [self::FIXTURES_FOLDER . 'translatable-fqn.html.php:2']], $catalogue->getMetadata('translatable-fqn single-quoted key'));
$this->assertEquals(['sources' => [self::FIXTURES_FOLDER . 'translatable-fqn.html.php:37']], $catalogue->getMetadata('translatable-fqn other-domain-test-no-params-short-array', 'not_messages'));
}
}
Loading
Loading