-
-
Notifications
You must be signed in to change notification settings - Fork 9.8k
[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
welcoMattic
wants to merge
10
commits into
symfony:8.1
Choose a base branch
from
welcoMattic:translation/php-ast-extractor-tests-rework
base: 8.1
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
bb37c68
Rework PhpAstExtractor tests organization
Jean-Beru 39199f7
review TestCase
Jean-Beru 049f9b2
revert source filename normalization in AbstractVisitor
Jean-Beru 21adde4
remove not used fixture
Jean-Beru a73ef03
fix Windows slashes
Jean-Beru 6c6d6ea
test TranslatableMessage FQCN
Jean-Beru 9e34c67
cs
Jean-Beru bd6c064
cs
Jean-Beru 9353d9c
remove useless fixtures and make extract method protected
Jean-Beru 757158e
fix Windows tests
Jean-Beru File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
207 changes: 15 additions & 192 deletions
207
src/Symfony/Component/Translation/Tests/Extractor/PhpAstExtractorTest.php
Large diffs are not rendered by default.
Oops, something went wrong.
35 changes: 35 additions & 0 deletions
35
src/Symfony/Component/Translation/Tests/Extractor/Visitor/AbstractVisitorTestCase.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| <?php | ||
|
|
||
| /* | ||
| * This file is part of the Symfony package. | ||
| * | ||
| * (c) Fabien Potencier <fabien@symfony.com> | ||
| * | ||
| * For the full copyright and license information, please view the LICENSE | ||
| * file that was distributed with this source code. | ||
| */ | ||
|
|
||
| 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 AbstractVisitorTestCase extends TestCase | ||
| { | ||
| /** | ||
| * @param string|iterable<string> $resource Files, a file or a directory | ||
| */ | ||
| protected function extract(NodeVisitor $visitor, string|iterable $resource): MessageCatalogue | ||
| { | ||
| $extractor = new PhpAstExtractor([$visitor]); | ||
| $extractor->setPrefix('prefix'); | ||
|
|
||
| $catalogue = new MessageCatalogue('en'); | ||
|
|
||
| $extractor->extract($resource, $catalogue); | ||
|
|
||
| return $catalogue; | ||
| } | ||
| } |
48 changes: 48 additions & 0 deletions
48
src/Symfony/Component/Translation/Tests/Extractor/Visitor/ConstraintVisitorTest.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| <?php | ||
|
|
||
| /* | ||
| * This file is part of the Symfony package. | ||
| * | ||
| * (c) Fabien Potencier <fabien@symfony.com> | ||
| * | ||
| * For the full copyright and license information, please view the LICENSE | ||
| * file that was distributed with this source code. | ||
| */ | ||
|
|
||
| namespace Symfony\Component\Translation\Tests\Extractor\Visitor; | ||
|
|
||
| use Symfony\Component\Translation\Extractor\Visitor\ConstraintVisitor; | ||
|
|
||
| final class ConstraintVisitorTest extends AbstractVisitorTestCase | ||
| { | ||
| private const FIXTURES_FOLDER = __DIR__.'/../../Fixtures/extractor-php-ast/constraint-visitor/'; | ||
|
|
||
| public function testExtractMessages() | ||
| { | ||
| $catalogue = $this->extract(new ConstraintVisitor(['NotBlank', 'Isbn', 'Length']), self::FIXTURES_FOLDER); | ||
|
|
||
| $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(), | ||
| ); | ||
|
|
||
| $fixtureFolder = str_replace(\DIRECTORY_SEPARATOR, '/', self::FIXTURES_FOLDER); | ||
|
|
||
| $this->assertEquals(['sources' => [$fixtureFolder.'validator-constraints.php:7']], $catalogue->getMetadata('message-in-constraint-attribute', 'validators')); | ||
| } | ||
| } |
116 changes: 116 additions & 0 deletions
116
src/Symfony/Component/Translation/Tests/Extractor/Visitor/TransMethodVisitorTest.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,116 @@ | ||
| <?php | ||
|
|
||
| /* | ||
| * This file is part of the Symfony package. | ||
| * | ||
| * (c) Fabien Potencier <fabien@symfony.com> | ||
| * | ||
| * For the full copyright and license information, please view the LICENSE | ||
| * file that was distributed with this source code. | ||
| */ | ||
|
|
||
| namespace Symfony\Component\Translation\Tests\Extractor\Visitor; | ||
|
|
||
| use Symfony\Component\Translation\Extractor\Visitor\TransMethodVisitor; | ||
|
|
||
| final class TransMethodVisitorTest extends AbstractVisitorTestCase | ||
| { | ||
| private const FIXTURES_FOLDER = __DIR__.'/../../Fixtures/extractor-php-ast/trans-method-visitor/'; | ||
| public const OTHER_DOMAIN = 'not_messages'; | ||
|
|
||
| public function testExtractMessages() | ||
| { | ||
| $catalogue = $this->extract(new TransMethodVisitor(), self::FIXTURES_FOLDER); | ||
|
|
||
| $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(), | ||
| ); | ||
|
|
||
| $fixtureFolder = str_replace(\DIRECTORY_SEPARATOR, '/', self::FIXTURES_FOLDER); | ||
|
|
||
| $this->assertEquals(['sources' => [$fixtureFolder.'translation.html.php:2']], $catalogue->getMetadata('single-quoted key')); | ||
| $this->assertEquals(['sources' => [$fixtureFolder.'translation.html.php:37']], $catalogue->getMetadata('other-domain-test-no-params-short-array', 'not_messages')); | ||
| $this->assertEquals(['sources' => [$fixtureFolder.'translation-73.html.php:8']], $catalogue->getMetadata("nowdoc\nindented\n further")); | ||
|
|
||
| $this->assertEquals(['sources' => [$fixtureFolder.'translatable-short.html.php:2']], $catalogue->getMetadata('translatable-short single-quoted key')); | ||
| $this->assertEquals(['sources' => [$fixtureFolder.'translatable-short.html.php:37']], $catalogue->getMetadata('translatable-short other-domain-test-no-params-short-array', 'not_messages')); | ||
|
|
||
| $this->assertEquals(['sources' => [$fixtureFolder.'translatable-short-fqn.html.php:2']], $catalogue->getMetadata('translatable-short-fqn single-quoted key')); | ||
| $this->assertEquals(['sources' => [$fixtureFolder.'translatable-short-fqn.html.php:37']], $catalogue->getMetadata('translatable-short-fqn other-domain-test-no-params-short-array', 'not_messages')); | ||
| } | ||
| } |
81 changes: 81 additions & 0 deletions
81
src/Symfony/Component/Translation/Tests/Extractor/Visitor/TranslatableMessageVisitorTest.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| <?php | ||
|
|
||
| /* | ||
| * This file is part of the Symfony package. | ||
| * | ||
| * (c) Fabien Potencier <fabien@symfony.com> | ||
| * | ||
| * For the full copyright and license information, please view the LICENSE | ||
| * file that was distributed with this source code. | ||
| */ | ||
|
|
||
| namespace Symfony\Component\Translation\Tests\Extractor\Visitor; | ||
|
|
||
| use Symfony\Component\Translation\Extractor\Visitor\TranslatableMessageVisitor; | ||
|
|
||
| final class TranslatableMessageVisitorTest extends AbstractVisitorTestCase | ||
| { | ||
| private const FIXTURES_FOLDER = __DIR__.'/../../Fixtures/extractor-php-ast/translatable-message-visitor/'; | ||
|
|
||
| public function testExtractMessages() | ||
| { | ||
| $catalogue = $this->extract(new TranslatableMessageVisitor(), self::FIXTURES_FOLDER); | ||
|
|
||
| $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(), | ||
| ); | ||
|
|
||
| $fixtureFolder = str_replace(\DIRECTORY_SEPARATOR, '/', self::FIXTURES_FOLDER); | ||
|
|
||
| $this->assertEquals(['sources' => [$fixtureFolder.'translatable.html.php:3']], $catalogue->getMetadata('translatable single-quoted key')); | ||
| $this->assertEquals(['sources' => [$fixtureFolder.'translatable.html.php:38']], $catalogue->getMetadata('translatable other-domain-test-no-params-short-array', 'not_messages')); | ||
|
|
||
| $this->assertEquals(['sources' => [$fixtureFolder.'translatable-fqn.html.php:2']], $catalogue->getMetadata('translatable-fqn single-quoted key')); | ||
| $this->assertEquals(['sources' => [$fixtureFolder.'translatable-fqn.html.php:37']], $catalogue->getMetadata('translatable-fqn other-domain-test-no-params-short-array', 'not_messages')); | ||
| } | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.