From 79813632744a49d5347b0ef059e5e9f5744f56d7 Mon Sep 17 00:00:00 2001 From: Jonas Raoni Soares da Silva Date: Sat, 23 Jul 2022 22:24:09 +0300 Subject: [PATCH] #282 Updated and added tests --- tests/BasePoLoaderTestCase.php | 291 +++++++++++++++++++++++++++++++++ tests/PoLoaderTest.php | 267 +----------------------------- tests/StrictPoLoaderTest.php | 196 ++++++++++++++++++++++ tests/assets/translations.po | 1 - 4 files changed, 491 insertions(+), 264 deletions(-) create mode 100644 tests/BasePoLoaderTestCase.php create mode 100644 tests/StrictPoLoaderTest.php diff --git a/tests/BasePoLoaderTestCase.php b/tests/BasePoLoaderTestCase.php new file mode 100644 index 00000000..76cdac63 --- /dev/null +++ b/tests/BasePoLoaderTestCase.php @@ -0,0 +1,291 @@ +createPoLoader(); + $translations = $loader->loadFile(__DIR__.'/assets/translations.po'); + + $description = $translations->getDescription(); + $this->assertSame( + <<<'EOT' +SOME DESCRIPTIVE TITLE +Copyright (C) YEAR Free Software Foundation, Inc. +This file is distributed under the same license as the PACKAGE package. +FIRST AUTHOR , YEAR. +EOT + , + $description + ); + + $this->assertSame(['fuzzy'], $translations->getFlags()->toArray()); + + $this->assertCount(14, $translations); + + $array = $translations->getTranslations(); + + $this->translation1(array_shift($array)); + $this->translation2(array_shift($array)); + $this->translation3(array_shift($array)); + $this->translation4(array_shift($array)); + $this->translation5(array_shift($array)); + $this->translation6(array_shift($array)); + $this->translation7(array_shift($array)); + $this->translation8(array_shift($array)); + $this->translation9(array_shift($array)); + $this->translation10(array_shift($array)); + $this->translation11(array_shift($array)); + $this->translation12(array_shift($array)); + $this->translation13(array_shift($array)); + $this->translation14(array_shift($array)); + + $headers = $translations->getHeaders()->toArray(); + + $this->assertCount(12, $headers); + + $this->assertSame('text/plain; charset=UTF-8', $headers['Content-Type']); + $this->assertSame('8bit', $headers['Content-Transfer-Encoding']); + $this->assertSame('', $headers['POT-Creation-Date']); + $this->assertSame('', $headers['PO-Revision-Date']); + $this->assertSame('', $headers['Last-Translator']); + $this->assertSame('', $headers['Language-Team']); + $this->assertSame('1.0', $headers['MIME-Version']); + $this->assertSame('bs', $headers['Language']); + $this->assertSame( + 'nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);', + $headers['Plural-Forms'] + ); + $this->assertSame('Poedit 1.6.5', $headers['X-Generator']); + $this->assertSame('gettext generator test', $headers['Project-Id-Version']); + $this->assertSame('testingdomain', $headers['X-Domain']); + + $this->assertSame('testingdomain', $translations->getDomain()); + $this->assertSame('bs', $translations->getLanguage()); + } + + private function translation1(Translation $translation) + { + $this->assertSame( + 'Ensure this value has at least %(limit_value)d character (it has %sd).', + $translation->getOriginal() + ); + $this->assertSame( + 'Ensure this value has at least %(limit_value)d characters (it has %sd).', + $translation->getPlural() + ); + $this->assertSame('', $translation->getTranslation()); + $this->assertSame(['', ''], $translation->getPluralTranslations()); + } + + private function translation2(Translation $translation) + { + $this->assertSame( + 'Ensure this value has at most %(limit_value)d character (it has %sd).', + $translation->getOriginal() + ); + $this->assertSame( + 'Ensure this value has at most %(limit_value)d characters (it has %sd).', + $translation->getPlural() + ); + $this->assertSame('', $translation->getTranslation()); + $this->assertSame(['', ''], $translation->getPluralTranslations()); + } + + private function translation3(Translation $translation) + { + $this->assertSame('%ss must be unique for %ss %ss.', $translation->getOriginal()); + $this->assertNull($translation->getPlural()); + $this->assertSame('%ss mora da bude jedinstven za %ss %ss.', $translation->getTranslation()); + $this->assertCount(0, $translation->getPluralTranslations()); + } + + private function translation4(Translation $translation) + { + $this->assertSame('and', $translation->getOriginal()); + $this->assertNull($translation->getPlural()); + $this->assertSame('i', $translation->getTranslation()); + $this->assertCount(0, $translation->getPluralTranslations()); + $this->assertSame(['c-format'], $translation->getFlags()->toArray()); + } + + private function translation5(Translation $translation) + { + $this->assertSame('Value %sr is not a valid choice.', $translation->getOriginal()); + $this->assertNull($translation->getPlural()); + $this->assertSame('', $translation->getTranslation()); + $this->assertCount(0, $translation->getPluralTranslations()); + $this->assertSame(['This is a extracted comment'], $translation->getExtractedComments()->toArray()); + } + + private function translation6(Translation $translation) + { + $this->assertSame('This field cannot be null.', $translation->getOriginal()); + $this->assertNull($translation->getPlural()); + $this->assertSame('Ovo polje ne može ostati prazno.', $translation->getTranslation()); + $this->assertCount(0, $translation->getPluralTranslations()); + $this->assertCount(1, $translation->getReferences()); + $this->assertSame(['C:/Users/Me/Documents/foo2.php' => [1]], $translation->getReferences()->toArray()); + } + + private function translation7(Translation $translation) + { + $this->assertSame('This field cannot be blank.', $translation->getOriginal()); + $this->assertNull($translation->getPlural()); + $this->assertSame('Ovo polje ne može biti prazno.', $translation->getTranslation()); + $this->assertCount(0, $translation->getPluralTranslations()); + $this->assertCount(1, $translation->getReferences()); + $this->assertSame(['C:/Users/Me/Documents/foo1.php' => []], $translation->getReferences()->toArray()); + } + + private function translation8(Translation $translation) + { + $this->assertSame('Field of type: %ss', $translation->getOriginal()); + $this->assertNull($translation->getPlural()); + $this->assertSame('Polje tipa: %ss', $translation->getTranslation()); + $this->assertCount(0, $translation->getPluralTranslations()); + $this->assertCount(2, $translation->getReferences()); + $this->assertSame( + [ + 'attributes/address/composer.php' => [8], + 'attributes/address/form.php' => [7], + ], + $translation->getReferences()->toArray() + ); + } + + private function translation9(Translation $translation) + { + $this->assertSame('Integer', $translation->getOriginal()); + $this->assertNull($translation->getPlural()); + $this->assertSame('Cijeo broj', $translation->getTranslation()); + $this->assertCount(0, $translation->getPluralTranslations()); + $this->assertCount(0, $translation->getReferences()); + $this->assertCount(1, $translation->getComments()); + $this->assertSame(['a simple line comment is above'], $translation->getComments()->toArray()); + } + + private function translation10(Translation $translation) + { + $this->assertSame('{test1}', $translation->getOriginal()); + $this->assertNull($translation->getPlural()); + $this->assertSame("test1\n
\n test2\n
\ntest3", $translation->getTranslation()); + $this->assertCount(0, $translation->getPluralTranslations()); + $this->assertCount(0, $translation->getComments()); + $this->assertCount(3, $translation->getReferences()); + $this->assertSame( + [ + '/var/www/test/test.php' => [96, 97], + '/var/www/test/test2.php' => [98], + ], + $translation->getReferences()->toArray() + ); + } + + private function translation11(Translation $translation) + { + $this->assertSame('{test2}', $translation->getOriginal()); + $this->assertNull($translation->getPlural()); + $this->assertSame("test1\n
\n test2\n
\ntest3", $translation->getTranslation()); + $this->assertCount(0, $translation->getPluralTranslations()); + $this->assertCount(0, $translation->getComments()); + $this->assertCount(1, $translation->getReferences()); + $this->assertSame( + ['/var/www/test/test.php' => [96]], + $translation->getReferences()->toArray() + ); + } + + private function translation12(Translation $translation) + { + $this->assertSame('Multibyte test', $translation->getOriginal()); + $this->assertNull($translation->getPlural()); + $this->assertSame('日本人は日本で話される言語です!', $translation->getTranslation()); + $this->assertCount(0, $translation->getPluralTranslations()); + $this->assertCount(0, $translation->getComments()); + $this->assertCount(0, $translation->getReferences()); + } + + private function translation13(Translation $translation) + { + $this->assertSame('Tabulation test', $translation->getOriginal()); + $this->assertNull($translation->getPlural()); + $this->assertSame("FIELD\tFIELD", $translation->getTranslation()); + $this->assertCount(0, $translation->getPluralTranslations()); + $this->assertCount(0, $translation->getComments()); + $this->assertCount(0, $translation->getReferences()); + } + + private function translation14(Translation $translation) + { + $this->assertSame('%s has been added to your cart.', $translation->getOriginal()); + $this->assertSame('%s have been added to your cart.', $translation->getPlural()); + $this->assertSame('%s has been added to your cart.', $translation->getTranslation()); + $this->assertSame(['%s have been added to your cart.'], $translation->getPluralTranslations()); + $this->assertCount(1, $translation->getComments()); + $this->assertCount(0, $translation->getReferences()); + } + + public function stringDecodeProvider() + { + return [ + ['"test"', 'test'], + ['"\'test\'"', "'test'"], + ['"Special chars: \\n \\t \\\\ "', "Special chars: \n \t \\ "], + ['"Newline\nSlash and n\\\\nend"', "Newline\nSlash and n\\nend"], + ['"Quoted \\"string\\" with %s"', 'Quoted "string" with %s'], + ['"\\\\x07 - aka \\\\a: \\a"', "\\x07 - aka \\a: \x07"], + ['"\\\\x08 - aka \\\\b: \\b"', "\\x08 - aka \\b: \x08"], + ['"\\\\x09 - aka \\\\t: \\t"', "\\x09 - aka \\t: \t"], + ['"\\\\x0a - aka \\\\n: \\n "', "\\x0a - aka \\n: \n "], + ['"\\\\x0b - aka \\\\v: \\v"', "\\x0b - aka \\v: \x0b"], + ['"\\\\x0c - aka \\\\f: \\f"', "\\x0c - aka \\f: \x0c"], + ['"\\\\x0d - aka \\\\r: \\r "', "\\x0d - aka \\r: \r "], + ['"\\\\x22 - aka \\": \\""', '\x22 - aka ": "'], + ['"\\\\x5c - aka \\\\: \\\\"', '\\x5c - aka \\: \\'], + ]; + } + + /** + * @dataProvider stringDecodeProvider + * @param mixed $source + * @param mixed $decoded + */ + public function testStringDecode($source, $decoded) + { + $po = <<createPoLoader()->loadString($po); + $this->assertSame($decoded, $translations->find(null, 'source')->getTranslation()); + } + + public function testMultilineDisabledTranslations() + { + $po = <<<'EOT' +#~ msgid "Last agent hours-description" +#~ msgstr "" +#~ "How many hours in the past can system look at finding the last agent? " +#~ "This parameter is only used if 'Call Last Agent' is set to 'YES'." +EOT; + $loader = $this->createPoLoader(); + $translations = $loader->loadString($po); + $translation = $translations->find(null, 'Last agent hours-description'); + + $this->assertTrue($translation->isDisabled()); + $this->assertEquals( + "How many hours in the past can system look at finding the last agent? This parameter is only used if 'Call Last Agent' is set to 'YES'.", + $translation->getTranslation() + ); + } +} diff --git a/tests/PoLoaderTest.php b/tests/PoLoaderTest.php index cfe4729f..3708690e 100644 --- a/tests/PoLoaderTest.php +++ b/tests/PoLoaderTest.php @@ -3,254 +3,14 @@ namespace Gettext\Tests; +use Gettext\Loader\Loader; use Gettext\Loader\PoLoader; -use Gettext\Translation; -use PHPUnit\Framework\TestCase; -class PoLoaderTest extends TestCase +class PoLoaderTest extends BasePoLoaderTestCase { - public function testPoLoader() + protected function createPoLoader(): Loader { - $loader = new PoLoader(); - $translations = $loader->loadFile(__DIR__.'/assets/translations.po'); - - $description = $translations->getDescription(); - $this->assertSame( - <<<'EOT' -SOME DESCRIPTIVE TITLE -Copyright (C) YEAR Free Software Foundation, Inc. -This file is distributed under the same license as the PACKAGE package. -FIRST AUTHOR , YEAR. -EOT - , - $description - ); - - $this->assertSame(['fuzzy'], $translations->getFlags()->toArray()); - - $this->assertCount(14, $translations); - - $array = $translations->getTranslations(); - - $this->translation1(array_shift($array)); - $this->translation2(array_shift($array)); - $this->translation3(array_shift($array)); - $this->translation4(array_shift($array)); - $this->translation5(array_shift($array)); - $this->translation6(array_shift($array)); - $this->translation7(array_shift($array)); - $this->translation8(array_shift($array)); - $this->translation9(array_shift($array)); - $this->translation10(array_shift($array)); - $this->translation11(array_shift($array)); - $this->translation12(array_shift($array)); - $this->translation13(array_shift($array)); - $this->translation14(array_shift($array)); - - $headers = $translations->getHeaders()->toArray(); - - $this->assertCount(12, $headers); - - $this->assertSame('text/plain; charset=UTF-8', $headers['Content-Type']); - $this->assertSame('8bit', $headers['Content-Transfer-Encoding']); - $this->assertSame('', $headers['POT-Creation-Date']); - $this->assertSame('', $headers['PO-Revision-Date']); - $this->assertSame('', $headers['Last-Translator']); - $this->assertSame('', $headers['Language-Team']); - $this->assertSame('1.0', $headers['MIME-Version']); - $this->assertSame('bs', $headers['Language']); - $this->assertSame( - 'nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);', - $headers['Plural-Forms'] - ); - $this->assertSame('Poedit 1.6.5', $headers['X-Generator']); - $this->assertSame('gettext generator test', $headers['Project-Id-Version']); - $this->assertSame('testingdomain', $headers['X-Domain']); - - $this->assertSame('testingdomain', $translations->getDomain()); - $this->assertSame('bs', $translations->getLanguage()); - } - - private function translation1(Translation $translation) - { - $this->assertSame( - 'Ensure this value has at least %(limit_value)d character (it has %sd).', - $translation->getOriginal() - ); - $this->assertSame( - 'Ensure this value has at least %(limit_value)d characters (it has %sd).', - $translation->getPlural() - ); - $this->assertSame('', $translation->getTranslation()); - $this->assertSame(['', ''], $translation->getPluralTranslations()); - } - - private function translation2(Translation $translation) - { - $this->assertSame( - 'Ensure this value has at most %(limit_value)d character (it has %sd).', - $translation->getOriginal() - ); - $this->assertSame( - 'Ensure this value has at most %(limit_value)d characters (it has %sd).', - $translation->getPlural() - ); - $this->assertSame('', $translation->getTranslation()); - $this->assertSame(['', ''], $translation->getPluralTranslations()); - } - - private function translation3(Translation $translation) - { - $this->assertSame('%ss must be unique for %ss %ss.', $translation->getOriginal()); - $this->assertNull($translation->getPlural()); - $this->assertSame('%ss mora da bude jedinstven za %ss %ss.', $translation->getTranslation()); - $this->assertCount(0, $translation->getPluralTranslations()); - } - - private function translation4(Translation $translation) - { - $this->assertSame('and', $translation->getOriginal()); - $this->assertNull($translation->getPlural()); - $this->assertSame('i', $translation->getTranslation()); - $this->assertCount(0, $translation->getPluralTranslations()); - $this->assertSame(['c-format'], $translation->getFlags()->toArray()); - } - - private function translation5(Translation $translation) - { - $this->assertSame('Value %sr is not a valid choice.', $translation->getOriginal()); - $this->assertNull($translation->getPlural()); - $this->assertSame('', $translation->getTranslation()); - $this->assertCount(0, $translation->getPluralTranslations()); - $this->assertSame(['This is a extracted comment'], $translation->getExtractedComments()->toArray()); - } - - private function translation6(Translation $translation) - { - $this->assertSame('This field cannot be null.', $translation->getOriginal()); - $this->assertNull($translation->getPlural()); - $this->assertSame('Ovo polje ne može ostati prazno.', $translation->getTranslation()); - $this->assertCount(0, $translation->getPluralTranslations()); - $this->assertCount(1, $translation->getReferences()); - $this->assertSame(['C:/Users/Me/Documents/foo2.php' => [1]], $translation->getReferences()->toArray()); - } - - private function translation7(Translation $translation) - { - $this->assertSame('This field cannot be blank.', $translation->getOriginal()); - $this->assertNull($translation->getPlural()); - $this->assertSame('Ovo polje ne može biti prazno.', $translation->getTranslation()); - $this->assertCount(0, $translation->getPluralTranslations()); - $this->assertCount(1, $translation->getReferences()); - $this->assertSame(['C:/Users/Me/Documents/foo1.php' => []], $translation->getReferences()->toArray()); - } - - private function translation8(Translation $translation) - { - $this->assertSame('Field of type: %ss', $translation->getOriginal()); - $this->assertNull($translation->getPlural()); - $this->assertSame('Polje tipa: %ss', $translation->getTranslation()); - $this->assertCount(0, $translation->getPluralTranslations()); - $this->assertCount(2, $translation->getReferences()); - $this->assertSame( - [ - 'attributes/address/composer.php' => [8], - 'attributes/address/form.php' => [7], - ], - $translation->getReferences()->toArray() - ); - } - - private function translation9(Translation $translation) - { - $this->assertSame('Integer', $translation->getOriginal()); - $this->assertNull($translation->getPlural()); - $this->assertSame('Cijeo broj', $translation->getTranslation()); - $this->assertCount(0, $translation->getPluralTranslations()); - $this->assertCount(0, $translation->getReferences()); - $this->assertCount(1, $translation->getComments()); - $this->assertSame(['a simple line comment is above'], $translation->getComments()->toArray()); - } - - private function translation10(Translation $translation) - { - $this->assertSame('{test1}', $translation->getOriginal()); - $this->assertNull($translation->getPlural()); - $this->assertSame("test1\n
\n test2\n
\ntest3", $translation->getTranslation()); - $this->assertCount(0, $translation->getPluralTranslations()); - $this->assertCount(0, $translation->getComments()); - $this->assertCount(3, $translation->getReferences()); - $this->assertSame( - [ - '/var/www/test/test.php' => [96, 97], - '/var/www/test/test2.php' => [98], - ], - $translation->getReferences()->toArray() - ); - } - - private function translation11(Translation $translation) - { - $this->assertSame('{test2}', $translation->getOriginal()); - $this->assertNull($translation->getPlural()); - $this->assertSame("test1\n
\n test2\n
\ntest3", $translation->getTranslation()); - $this->assertCount(0, $translation->getPluralTranslations()); - $this->assertCount(0, $translation->getComments()); - $this->assertCount(1, $translation->getReferences()); - $this->assertSame( - ['/var/www/test/test.php' => [96]], - $translation->getReferences()->toArray() - ); - } - - private function translation12(Translation $translation) - { - $this->assertSame('Multibyte test', $translation->getOriginal()); - $this->assertNull($translation->getPlural()); - $this->assertSame('日本人は日本で話される言語です!', $translation->getTranslation()); - $this->assertCount(0, $translation->getPluralTranslations()); - $this->assertCount(0, $translation->getComments()); - $this->assertCount(0, $translation->getReferences()); - } - - private function translation13(Translation $translation) - { - $this->assertSame('Tabulation test', $translation->getOriginal()); - $this->assertNull($translation->getPlural()); - $this->assertSame("FIELD\tFIELD", $translation->getTranslation()); - $this->assertCount(0, $translation->getPluralTranslations()); - $this->assertCount(0, $translation->getComments()); - $this->assertCount(0, $translation->getReferences()); - } - - private function translation14(Translation $translation) - { - $this->assertSame('%s has been added to your cart.', $translation->getOriginal()); - $this->assertSame('%s have been added to your cart.', $translation->getPlural()); - $this->assertSame('%s has been added to your cart.', $translation->getTranslation()); - $this->assertSame(['%s have been added to your cart.'], $translation->getPluralTranslations()); - $this->assertCount(1, $translation->getComments()); - $this->assertCount(0, $translation->getReferences()); - } - - public function stringDecodeProvider() - { - return [ - ['"test"', 'test'], - ['"\'test\'"', "'test'"], - ['"Special chars: \\n \\t \\\\ "', "Special chars: \n \t \\ "], - ['"Newline\nSlash and n\\\\nend"', "Newline\nSlash and n\\nend"], - ['"Quoted \\"string\\" with %s"', 'Quoted "string" with %s'], - ['"\\\\x07 - aka \\\\a: \\a"', "\\x07 - aka \\a: \x07"], - ['"\\\\x08 - aka \\\\b: \\b"', "\\x08 - aka \\b: \x08"], - ['"\\\\x09 - aka \\\\t: \\t"', "\\x09 - aka \\t: \t"], - ['"\\\\x0a - aka \\\\n: \\n"', "\\x0a - aka \\n: \n"], - ['"\\\\x0b - aka \\\\v: \\v"', "\\x0b - aka \\v: \x0b"], - ['"\\\\x0c - aka \\\\f: \\f"', "\\x0c - aka \\f: \x0c"], - ['"\\\\x0d - aka \\\\r: \\r"', "\\x0d - aka \\r: \r"], - ['"\\\\x22 - aka \\": \\""', '\x22 - aka ": "'], - ['"\\\\x5c - aka \\\\: \\\\"', '\\x5c - aka \\: \\'], - ]; + return new PoLoader(); } /** @@ -262,23 +22,4 @@ public function testStringDecode($source, $decoded) { $this->assertSame($decoded, PoLoader::decode($source)); } - - public function testMultilineDisabledTranslations() - { - $po = <<<'EOT' -#~ msgid "Last agent hours-description" -#~ msgstr "" -#~ "How many hours in the past can system look at finding the last agent? " -#~ "This parameter is only used if 'Call Last Agent' is set to 'YES'." -EOT; - $loader = new PoLoader(); - $translations = $loader->loadString($po); - $translation = $translations->find(null, 'Last agent hours-description'); - - $this->assertTrue($translation->isDisabled()); - $this->assertEquals( - "How many hours in the past can system look at finding the last agent? This parameter is only used if 'Call Last Agent' is set to 'YES'.", - $translation->getTranslation() - ); - } } diff --git a/tests/StrictPoLoaderTest.php b/tests/StrictPoLoaderTest.php new file mode 100644 index 00000000..43830b84 --- /dev/null +++ b/tests/StrictPoLoaderTest.php @@ -0,0 +1,196 @@ +createPoLoader()->loadString($po); + $this->assertEquals($translations->find('ctx', 'original')->getTranslation(), 'translation'); + $this->assertEquals($translations->find('ctx', 'original')->getComments()->toArray()[0], ' comment'); + } + + public function badFormattedPoProvider(): array + { + return [ + 'Duplicated entry' => [ + '/Duplicated entry/', + 'msgid"original" + msgstr"translation" + + msgid"original" + msgstr"translation 2"', + ], + 'msgstr before msgid' => [ + '/Expected msgid/', + 'msgstr "translation" + msgid "original"', + ], + 'Comments should come before the definitions' => [ + '/Expected msgstr/', + 'msgid "original" + # Unexpected comment + msgstr "translation"', + ], + 'msgid_plural requires an indexed msgstr' => [ + '/Expected character "\\["/', + 'msgid "original" + msgid_plural "plural" + msgstr "translation"', + ], + 'msgstr with a bad index' => [ + '/The msgstr has an invalid index/', + 'msgid "original" + msgid_plural "plural" + msgstr[0] "translation" + msgstr[2] "translation"', + ], + 'msgstr with a bad index 2' => [ + '/Expected character "]"/', + 'msgid "original" + msgid_plural "plural" + msgstr[0] "translation" + msgstr[1s] "translation"', + ], + 'Incomplete translation' => [ + '/Expected msgstr/', + 'msgid "original"', + ], + 'Bad quoted msgid' => [ + '/Expected an opening quote/', + 'msgid original + msgstr "translation"', + ], + 'Unquoted newline' => [ + '/Newline character must be escaped/', + 'msgid "original" + msgstr "trans + lation"', + ], + 'Bad escaped octal' => [ + '/Invalid quoted character/', + 'msgid "original" + msgstr "translation\8"', + ], + 'Out of range octal' => [ + '/Octal value out of range/', + 'msgid "original" + msgstr "translation\777"', + ], + 'Bad escaped hex' => [ + '/Expected at least one occurrence of hexadecimal/', + 'msgid "original" + msgstr "translation\xGG"', + ], + 'Bad escaped hex' => [ + '/Expected at least one occurrence of hexadecimal/', + 'msgid "original" + msgstr "translation\xGG"', + ], + 'Bad escaped unicode' => [ + '/Expected at least one occurrence of hexadecimal/', + 'msgid "original" + msgstr "translation\uZZ"', + ], + 'Disabled translations (#~) cannot appear after previous translations (#|)' => [ + '/Inconsistent use of #~/', + '#|msgid "previous" + #~msgid "disabled" + #~msgstr "disabled translation" + msgid "original" + msgstr "translation"', + ], + 'Invalid identifier' => [ + '/Expected msgid/', + 'unknown "original" + msgstr "translation"', + ], + 'msgctxt of a previous translation must come before its msgid' => [ + '/Cannot redeclare the previous comment/', + '#|msgid "previous" + #|msgctxt "previous context" + #|msgid_plural "previous context" + msgid "original" + msgstr "translation"', + ], + // The checks below depends on the $throwOnWarning = true + 'msgid, msgid_plural and msgstr cannot begin nor end with newline' => [ + '/msgstr cannot start nor end with a newline/', + 'msgid "original" + msgstr "translation\n"', + true, + ], + 'Missing header' => [ + '/The loaded string has no header translation/', + 'msgid "original" + msgstr "translation"', + true, + ], + 'Duplicated header' => [ + '/Header already defined/', + 'msgid "" + msgstr "Header: \\n" + "Header: \\n"', + true, + ], + 'Malformed header name' => [ + '/Malformed header name/', + 'msgid "" + msgstr "Header\\n"', + true, + ], + 'Missing standard headers Language/Plural-Forms/Content-Type' => [ + '/header not declared or empty/', + 'msgid "" + msgstr "Header: Value\\n"', + true, + ], + 'Two plural forms with just one plural translation' => [ + '/The translation doesn\'t have all the \\d+ plural forms/', + 'msgid "" + msgstr "Language: en_US\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Plural-Forms: nplurals=2; plural=n != 1;\n" + + msgid "original" + msgid_plural "plural" + msgstr[0] "translation"', + true, + ], + ]; + } + + /** + * @dataProvider badFormattedPoProvider + */ + public function testBadFormattedPo(string $exceptionPattern, string $po, bool $throwOnWarning = false): void + { + $this->expectExceptionMessageMatches($exceptionPattern); + $this->createPoLoader()->loadString($po, null, $throwOnWarning); + } +} diff --git a/tests/assets/translations.po b/tests/assets/translations.po index b172a8ed..d37fbf0b 100644 --- a/tests/assets/translations.po +++ b/tests/assets/translations.po @@ -2,7 +2,6 @@ # Copyright (C) YEAR Free Software Foundation, Inc. # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. -# #, fuzzy msgid "" msgstr ""