def test_multiline_context(self): buf = StringIO(''' msgctxt "a really long " "message context " "why?" msgid "mid" msgstr "mst" ''') catalog = pofile.read_po(buf) self.assertEqual(1, len(catalog)) message = catalog.get('mid', context="a really long message context why?") assert message is not None self.assertEqual("a really long message context why?", message.context)
def test_fuzzy_header(self): buf = StringIO(r'''\ # Translations template for AReallyReallyLongNameForAProject. # Copyright (C) 2007 ORGANIZATION # This file is distributed under the same license as the # AReallyReallyLongNameForAProject project. # FIRST AUTHOR <EMAIL@ADDRESS>, 2007. # #, fuzzy ''') catalog = pofile.read_po(buf) self.assertEqual(1, len(list(catalog))) self.assertEqual(True, list(catalog)[0].fuzzy)
def test_check_tags_in_content_tag_error(): buf = StringIO( '<html><div title="hello world!" i18n> hello <br><strong><div>world</div></strong>!\n</div>\n<div alt="hello world!" i18n> hello world!</div></html>' ) passed = False try: messages = list( extract_angularjs(buf, [], [], {"include_attributes": "title alt"})) except TagNotAllowedException: passed = True assert passed
def test_read_multiline(self): buf = StringIO(r'''msgid "" "Here's some text that\n" "includesareallylongwordthatmightbutshouldnt" " throw us into an infinite " "loop\n" msgstr ""''') catalog = pofile.read_po(buf) self.assertEqual(1, len(catalog)) message = list(catalog)[1] self.assertEqual( "Here's some text that\nincludesareallylongwordthat" "mightbutshouldnt throw us into an infinite loop\n", message.id)
def test_obsolete_message_ignored(self): buf = StringIO(r'''# This is an obsolete message #~ msgid "foo" #~ msgstr "Voh" # This message is not obsolete #: main.py:1 msgid "bar" msgstr "Bahr" ''') catalog = pofile.read_po(buf, ignore_obsolete=True) self.assertEqual(1, len(catalog)) self.assertEqual(0, len(catalog.obsolete))
def test_obsolete_message(self): buf = StringIO(r'''# This is an obsolete message #. Developer comment #: utils.py:3 #, fuzzy #| msgctxt "previous context" #| msgid "fuu" #~ msgctxt "context" #~ msgid "foo" #~ msgstr "Voh" #~ This is another obsolete message #~. Another developer comment #~: utils.py:3 #~, fuzzy #~| msgctxt "previous context" #~| msgid "fus" #~ msgctxt "context" #~ msgid "fos" #~ msgstr "Vohs" # This message is not obsolete #: main.py:1 msgid "bar" msgstr "Bahr" ''') catalog = pofile.read_po(buf) self.assertEqual(1, len(catalog)) self.assertEqual(2, len(catalog.obsolete)) message = catalog.obsolete[u'foo'] self.assertEqual(u'foo', message.id) self.assertEqual(u'Voh', message.string) self.assertEqual([('utils.py', 3)], message.locations) self.assertEqual({'fuzzy'}, message.flags) self.assertEqual(['Developer comment'], message.extracted_comments) self.assertEqual(['This is an obsolete message'], message.translator_comments) self.assertEqual(u'fuu', message.previous_id) self.assertEqual(u'previous context', message.previous_context) self.assertEqual(u'context', message.context) message = catalog.obsolete[u'fos'] self.assertEqual(u'fos', message.id) self.assertEqual(u'Vohs', message.string) self.assertEqual([('utils.py', 3)], message.locations) self.assertEqual({'fuzzy'}, message.flags) self.assertEqual(['Another developer comment'], message.extracted_comments) self.assertEqual(['This is another obsolete message'], message.translator_comments) self.assertEqual(u'fus', message.previous_id) self.assertEqual(u'previous context', message.previous_context) self.assertEqual(u'context', message.context)
def test_do_not_extract_entire_div_block(): buf = StringIO( '<html><div no-i18n>hello world!\n<h2 title="some title">Heading 2</h2>\n<div>another div <p>text1</p></div><p>text2</p></div>\n<h3 title="extracted title">Heading 3</h3></html>' ) messages = list( extract_angularjs(buf, [], [], { "include_attributes": "title alt", "include_tags": "p h2 h3" })) assert messages == [ (4, 'gettext', u'extracted title', ['title'], ()), (4, 'gettext', u'Heading 3', [], ()), ]
def test_empty_string_msgid(self): buf = BytesIO(b"""\ msg = _('') """) stderr = sys.stderr sys.stderr = StringIO() try: messages = \ list(extract.extract('python', buf, extract.DEFAULT_KEYWORDS, [], {})) self.assertEqual([], messages) assert 'warning: Empty msgid.' in sys.stderr.getvalue() finally: sys.stderr = stderr
def test_do_not_extract_entire_div_block_inner_attributes_error(): for attr in ["i18n", "no-i18n", "i18n-title", "no-i18n-title"]: buf = StringIO( '<html><div no-i18n>hello world!\n<h2 title="some title" %s>Heading 2</h2>\n<div>another div <p>text1</p></div><p>text2</p>\n<h3 title="extracted title">Heading 3</h3></div></html>' % attr) passed = False try: messages = list( extract_angularjs(buf, [], [], { "include_attributes": "title alt", "include_tags": "p h2 h3" })) except ExtractAttributeNotAllowedException: passed = True assert passed
def test_with_previous(self): buf = StringIO(r''' #: main.py:1 #| msgctxt "f" #| msgid "fo" msgid "foo" msgstr "Voh" ''') catalog = pofile.read_po(buf) self.assertEqual(1, len(catalog)) message = catalog["foo"] self.assertEqual("foo", message.id) self.assertEqual("Voh", message.string) self.assertEqual([("main.py", 1)], message.locations) self.assertEqual("f", message.previous_context) self.assertEqual("fo", message.previous_id)
def test_check_tag_attributes_in_content_ok(): buf = StringIO( '<html><div i18n>hello <br><strong><a href="www.helloworld.com" >world</a></strong>!</div></html>' ) messages = list( extract_angularjs( buf, [], [], { "include_attributes": "title alt", "allowed_tags": "a br strong", "allowed_attributes_a": "href" })) assert messages == [ (1, 'gettext', u'hello <br><strong><a href="www.helloworld.com">world</a></strong>!', [], ()) ]
def test_obsolete_message(self): buf = StringIO(r'''# This is an obsolete message #~ msgid "foo" #~ msgstr "Voh" # This message is not obsolete #: main.py:1 msgid "bar" msgstr "Bahr" ''') catalog = pofile.read_po(buf) self.assertEqual(1, len(catalog)) self.assertEqual(1, len(catalog.obsolete)) message = catalog.obsolete[u'foo'] self.assertEqual(u'foo', message.id) self.assertEqual(u'Voh', message.string) self.assertEqual(['This is an obsolete message'], message.user_comments)
def test_auto_extract(): buf = StringIO( '<html><h2>Heading 2</h2>\n<h3>Heading 3</h3>\n<p>Hello world!</p><p i18n="useful comment for translator">Hello again.</p></html>' ) messages = list( extract_angularjs( buf, [], [], { "include_tags": "p h2 h3", "allowed_tags": "span strong br i a", "allowed_attributes_i": "class", "allowed_attributes_span": "class", "allowed_attributes_a": "target ng-href" })) assert messages == [(1, 'gettext', u'Heading 2', [], ()), (2, 'gettext', u'Heading 3', [], ()), (3, 'gettext', u'Hello world!', [], ()), (3, 'gettext', u'Hello again.', ["useful comment for translator"], ())]
def test_obsolete_message_ignored(self): buf = StringIO(r'''# User comment #. Developer Comment #: utils.py:3 #, fuzzy #| msgctxt "previous context" #| msgid "foo" #~ msgctxt "context" #~ msgid "bar" #~ msgstr "Bahr" # This message is not obsolete #: main.py:1 msgid "bar" msgstr "Bahr" ''') catalog = pofile.read_po(buf, ignore_obsolete=True) self.assertEqual(1, len(catalog)) self.assertEqual(0, len(catalog.obsolete))
def render_pages(translations_path: Path, template_path: Path, output_path: Path): if not output_path.exists(): output_path.mkdir() translations = {} for directory in translations_path.glob('??-??'): if directory.is_dir() and directory.stem != 'en-US': translations[directory.stem] = directory for template in template_path.glob('*.php'): print(f'Rendering {template}') with template.open('r', encoding='UTF-8') as tpl_file: raw_template = tpl_file.read() for (translation, path) in translations.items(): try: translation_file = translations_path / translation / ( template.stem + '.po') if not translation_file.exists(): print( f'\t\t⚠ Translation of file {template.name} for language {translation} is missing: {translation_file}' ) continue with translation_file.open('r', encoding='UTF-8') as lang_file: raw_messages = read_po(StringIO(lang_file.read()), charset='UTF-8') messages = {} for message in raw_messages: messages[message.id] = _convert_markdown( message.string) output = _render_page(raw_template, messages) output_file = output_path / translation / template.name if not output_file.parent.exists(): output_file.parent.mkdir() with open(output_path / translation / template.name, 'w', encoding='UTF-8') as out_file: out_file.write(output) print( f'\t\t✅ Generated {out_file.name} for {translation}' ) except Exception as e: print(f'\t\t⚠ Failed to generate for {translation}: {e}')
def test_unit_following_multi_line_obsolete_message(self): buf = StringIO(r'''# This is an obsolete message #~ msgid "" #~ "foo" #~ "fooooooo" #~ msgstr "" #~ "Voh" #~ "Vooooh" # This message is not obsolete #: main.py:1 msgid "bar" msgstr "Bahr" ''') catalog = pofile.read_po(buf) self.assertEqual(1, len(catalog)) message = catalog[u'bar'] self.assertEqual(u'bar', message.id) self.assertEqual(u'Bahr', message.string) self.assertEqual(['This message is not obsolete'], message.user_comments)
def test_unit_before_obsolete_is_not_obsoleted(self): buf = StringIO(r''' # This message is not obsolete #: main.py:1 msgid "bar" msgstr "Bahr" # This is an obsolete message #~ msgid "" #~ "foo" #~ "fooooooo" #~ msgstr "" #~ "Voh" #~ "Vooooh" ''') catalog = pofile.read_po(buf) self.assertEqual(1, len(catalog)) message = catalog[u'bar'] self.assertEqual(u'bar', message.id) self.assertEqual(u'Bahr', message.string) self.assertEqual(['This message is not obsolete'], message.translator_comments)
def test_header_entry(self): buf = StringIO(r''' # SOME DESCRIPTIVE TITLE. # Copyright (C) 2007 THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR <EMAIL@ADDRESS>, 2007. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: 3.15\n" "Report-Msgid-Bugs-To: Fliegender Zirkus <*****@*****.**>\n" "POT-Creation-Date: 2007-09-27 11:19+0700\n" "PO-Revision-Date: 2007-09-27 21:42-0700\n" "Last-Translator: John <*****@*****.**>\n" "Language: de\n" "Language-Team: German Lang <*****@*****.**>\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=iso-8859-2\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 1.0dev-r313\n" ''') catalog = pofile.read_po(buf) self.assertEqual(1, len(list(catalog))) self.assertEqual(u'3.15', catalog.version) self.assertEqual(u'Fliegender Zirkus <*****@*****.**>', catalog.msgid_bugs_address) self.assertEqual(datetime(2007, 9, 27, 11, 19, tzinfo=FixedOffsetTimezone(7 * 60)), catalog.creation_date) self.assertEqual(u'John <*****@*****.**>', catalog.last_translator) self.assertEqual(Locale('de'), catalog.locale) self.assertEqual(u'German Lang <*****@*****.**>', catalog.language_team) self.assertEqual(u'iso-8859-2', catalog.charset) self.assertEqual(True, list(catalog)[0].fuzzy)
def test_utf8_encoding(): buf = StringIO( '<html><div i18n>Příliš žluťoučký kůň úpěl ďábelské ódy.</div></html>') messages = list(extract_angularjs(buf, [], [], {})) assert messages == [(1, 'gettext', u'Příliš žluťoučký kůň úpěl ďábelské ódy.', [], ())]
def test_angularjs_expression(): buf = StringIO('<html><div i18n>hello {{ name }}!</div></html>') messages = list(extract_angularjs(buf, [], [], {})) assert messages == [(1, 'gettext', 'hello {{ name }}!', [], ("angularjs-format", ))]
def test_multi_line_obsolete_message(self): buf = StringIO(r'''# Here's a user comment that covers multiple lines, and should still be # handled correctly. #. Here's a developer comment that covers multiple lines, and should still be #. handled correctly. #: utils.py:3 #, fuzzy #| msgctxt "" #| "Here's a previous context that covers\n" #| "multiple lines, and should still be handled\n" #| "correctly.\n" #| msgid "previous\n" #| "foo" #~ msgctxt "" #~ "Here's a context that covers\n" #~ "multiple lines, and should still be handled\n" #~ "correctly.\n" #~ msgid "" #~ "foo" #~ "foo" #~ msgstr "" #~ "Here's a message that covers\n" #~ "multiple lines, and should still be handled\n" #~ "correctly.\n" #~ Here's a user comment that covers multiple lines, and should still be #~ handled correctly. #~. Here's a developer comment that covers multiple lines, and should still be #~. handled correctly. #~: utils.py:3 #~, fuzzy #~| msgctxt "" #~| "Here's a previous context that covers\n" #~| "multiple lines, and should still be handled\n" #~| "correctly.\n" #| msgid "previous\n" #| "fos" #~ msgctxt "" #~ "Here's a context that covers\n" #~ "multiple lines, and should still be handled\n" #~ "correctly.\n" #~ msgid "" #~ "fos" #~ "fos" #~ msgstr "" #~ "Here's a message that covers\n" #~ "multiple lines, and should still be handled\n" #~ "correctly.\n" # This message is not obsolete #: main.py:1 msgid "bar" msgstr "Bahr" ''') catalog = pofile.read_po(buf) self.assertEqual(2, len(catalog.obsolete)) message = catalog.obsolete[u'foofoo'] self.assertEqual(u'foofoo', message.id) self.assertEqual(r"""Here's a message that covers multiple lines, and should still be handled correctly. """, message.string) self.assertEqual([('utils.py', 3)], message.locations) self.assertEqual({'fuzzy'}, message.flags) self.assertEqual(["Here's a developer comment that covers multiple lines, and should still be", "handled correctly."], message.extracted_comments) self.assertEqual(["Here's a user comment that covers multiple lines, and should still be", "handled correctly."], message.translator_comments) self.assertEqual(u'previous\nfoo', message.previous_id) self.assertEqual(r"""Here's a previous context that covers multiple lines, and should still be handled correctly. """, message.previous_context) self.assertEqual(r"""Here's a context that covers multiple lines, and should still be handled correctly. """, message.context) message = catalog.obsolete[u'fosfos'] self.assertEqual(u'fosfos', message.id) self.assertEqual(r"""Here's a message that covers multiple lines, and should still be handled correctly. """, message.string) self.assertEqual([('utils.py', 3)], message.locations) self.assertEqual({'fuzzy'}, message.flags) self.assertEqual(["Here's a developer comment that covers multiple lines, and should still be", "handled correctly."], message.extracted_comments) self.assertEqual(["Here's a user comment that covers multiple lines, and should still be", "handled correctly."], message.translator_comments) self.assertEqual(u'previous\nfos', message.previous_id) self.assertEqual(r"""Here's a previous context that covers multiple lines, and should still be handled correctly. """, message.previous_context) self.assertEqual(r"""Here's a context that covers multiple lines, and should still be handled correctly. """, message.context)
def test_comments(): buf = StringIO('<html><div i18n="page title">hello world!</div></html>') messages = list(extract_angularjs(buf, [], [], {})) assert messages == [(1, 'gettext', 'hello world!', ['page title'], ())]
def test_attribute(): buf = StringIO('<html><div title="some title">hello world!</div></html>') messages = list( extract_angularjs(buf, [], [], {"include_attributes": "title"})) assert messages == [(1, 'gettext', 'some title', ["title"], ())]
def test_extract_attribute2(): buf = StringIO( '<html><div><strong something="some title" i18n-something>hello world!</strong></div></html>' ) messages = list(extract_angularjs(buf, [], [], {})) assert messages == [(1, 'gettext', 'some title', ["something"], ())]
def test_preserve_locale(self): buf = StringIO(r'''msgid "foo" msgstr "Voh"''') catalog = pofile.read_po(buf, locale='en_US') self.assertEqual(Locale('en', 'US'), catalog.locale)
def test_extract_no_tags(): buf = StringIO('<html></html>') messages = list(extract_angularjs(buf, [], [], {})) assert messages == []