def test_warn_if_empty_string_msgid_found_in_context_aware_extraction_method( self): buf = StringIO("\nmsg = pgettext('ctxt', '')\n") stderr = sys.stderr sys.stderr = StringIO() try: messages = extract.extract('python', buf) self.assertEqual([], list(messages)) assert 'warning: Empty msgid.' in sys.stderr.getvalue() finally: sys.stderr = stderr
def setUp(self): self.datadir = os.path.join(os.path.dirname(__file__), 'data') self.orig_working_dir = os.getcwd() self.orig_argv = sys.argv self.orig_stdout = sys.stdout self.orig_stderr = sys.stderr sys.argv = ['pybabel'] sys.stdout = StringIO() sys.stderr = StringIO() os.chdir(self.datadir) self._remove_log_handlers() self.cli = frontend.CommandLineInterface()
def test_empty_string_msgid(self): buf = StringIO("""\ 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_with_context(self): buf = StringIO(r'''# Some string in the menu #: main.py:1 msgctxt "Menu" msgid "foo" msgstr "Voh" # Another string in the menu #: main.py:2 msgctxt "Menu" msgid "bar" msgstr "Bahr" ''') catalog = pofile.read_po(buf, ignore_obsolete=True) self.assertEqual(2, len(catalog)) message = catalog.get('foo', context='Menu') self.assertEqual('Menu', message.context) message = catalog.get('bar', context='Menu') self.assertEqual('Menu', message.context) # And verify it pass through write_po out_buf = BytesIO() pofile.write_po(out_buf, catalog, omit_header=True) assert out_buf.getvalue().strip() == b(buf.getvalue().strip()), \ out_buf.getvalue()
def test_comments_with_calls_that_spawn_multiple_lines(self): buf = StringIO("""\ # NOTE: This Comment SHOULD Be Extracted add_notice(req, ngettext("Catalog deleted.", "Catalogs deleted.", len(selected))) # NOTE: This Comment SHOULD Be Extracted add_notice(req, _("Locale deleted.")) # NOTE: This Comment SHOULD Be Extracted add_notice(req, ngettext("Foo deleted.", "Foos deleted.", len(selected))) # NOTE: This Comment SHOULD Be Extracted # NOTE: And This One Too add_notice(req, ngettext("Bar deleted.", "Bars deleted.", len(selected))) """) messages = list( extract.extract_python(buf, ('ngettext', '_'), ['NOTE:'], {'strip_comment_tags': False})) self.assertEqual((6, '_', 'Locale deleted.', ['NOTE: This Comment SHOULD Be Extracted']), messages[1]) self.assertEqual( (10, 'ngettext', ('Foo deleted.', 'Foos deleted.', None), ['NOTE: This Comment SHOULD Be Extracted']), messages[2]) self.assertEqual( (3, 'ngettext', ('Catalog deleted.', 'Catalogs deleted.', None), ['NOTE: This Comment SHOULD Be Extracted']), messages[0]) self.assertEqual( (15, 'ngettext', ('Bar deleted.', 'Bars deleted.', None), [ 'NOTE: This Comment SHOULD Be Extracted', 'NOTE: And This One Too' ]), messages[3])
def _get_mappings(self): mappings = {} if self.mapping_file: fileobj = open(self.mapping_file, 'U') try: method_map, options_map = parse_mapping(fileobj) for dirname in self.input_dirs: mappings[dirname] = method_map, options_map finally: fileobj.close() elif getattr(self.distribution, 'message_extractors', None): message_extractors = self.distribution.message_extractors for dirname, mapping in message_extractors.items(): if isinstance(mapping, string_types): method_map, options_map = parse_mapping(StringIO(mapping)) else: method_map, options_map = [], {} for pattern, method, options in mapping: method_map.append((pattern, method)) options_map[pattern] = options or {} mappings[dirname] = method_map, options_map else: for dirname in self.input_dirs: mappings[dirname] = DEFAULT_MAPPING, {} return mappings
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-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('3.15', catalog.version) self.assertEqual('Fliegender Zirkus <*****@*****.**>', catalog.msgid_bugs_address) self.assertEqual( datetime(2007, 9, 27, 11, 19, tzinfo=FixedOffsetTimezone(7 * 60)), catalog.creation_date) self.assertEqual('John <*****@*****.**>', catalog.last_translator) self.assertEqual('German Lang <*****@*****.**>', catalog.language_team) self.assertEqual('iso-8859-2', catalog.charset) self.assertEqual(True, list(catalog)[0].fuzzy)
def test_misplaced_comments(self): buf = StringIO("""\ /* NOTE: this won't show up */ foo() /* NOTE: this will */ msg = _('Something') // NOTE: this will show up // too. msg = _('Something else') // NOTE: but this won't bar() _('no comment here') """) messages = list(extract.extract_javascript(buf, ('_', ), ['NOTE:'], {})) self.assertEqual(u('Something'), messages[0][2]) self.assertEqual([u('NOTE: this will')], messages[0][3]) self.assertEqual(u('Something else'), messages[1][2]) self.assertEqual([u('NOTE: this will show up'), 'too.'], messages[1][3]) self.assertEqual(u('no comment here'), messages[2][2]) self.assertEqual([], messages[2][3])
def test_nested_calls(self): buf = StringIO("""\ msg1 = _(i18n_arg.replace(r'\"', '"')) msg2 = ungettext(i18n_arg.replace(r'\"', '"'), multi_arg.replace(r'\"', '"'), 2) msg3 = ungettext("Babel", multi_arg.replace(r'\"', '"'), 2) msg4 = ungettext(i18n_arg.replace(r'\"', '"'), "Babels", 2) msg5 = ungettext('bunny', 'bunnies', random.randint(1, 2)) msg6 = ungettext(arg0, 'bunnies', random.randint(1, 2)) msg7 = _(hello.there) msg8 = gettext('Rabbit') msg9 = dgettext('wiki', model.addPage()) msg10 = dngettext(getDomain(), 'Page', 'Pages', 3) """) messages = list( extract.extract_python(buf, extract.DEFAULT_KEYWORDS.keys(), [], {})) self.assertEqual([(1, '_', None, []), (2, 'ungettext', (None, None, None), []), (3, 'ungettext', (u('Babel'), None, None), []), (4, 'ungettext', (None, u('Babels'), None), []), (5, 'ungettext', (u('bunny'), u('bunnies'), None), []), (6, 'ungettext', (None, u('bunnies'), None), []), (7, '_', None, []), (8, 'gettext', u('Rabbit'), []), (9, 'dgettext', (u('wiki'), None), []), (10, 'dngettext', (None, u('Page'), u('Pages'), None), [])], messages)
def test_ignore_function_definitions(self): buf = StringIO("""\ function gettext(value) { return translations[language][value] || value; }""") messages = list(extract.extract_javascript(buf, ('gettext', ), [], {})) self.assertEqual(messages, [])
def test_comment_tag(self): buf = StringIO(""" # NOTE: A translation comment msg = _(u'Foo Bar') """) messages = list(extract.extract_python(buf, ('_', ), ['NOTE:'], {})) self.assertEqual(u('Foo Bar'), messages[0][2]) self.assertEqual([u('NOTE: A translation comment')], messages[0][3])
def test_concatenated_strings(self): buf = StringIO("""\ foobar = _('foo' 'bar') """) messages = list( extract.extract_python(buf, list(extract.DEFAULT_KEYWORDS.keys()), [], {})) self.assertEqual(u('foobar'), messages[0][2])
def test_utf8_message_with_magic_comment(self): buf = StringIO("""# -*- coding: utf-8 -*- # NOTE: hello msg = _('Bonjour à tous') """) messages = list(extract.extract_python(buf, ('_', ), ['NOTE:'], {})) self.assertEqual(u('Bonjour \xe0 tous'), messages[0][2]) self.assertEqual([u('NOTE: hello')], messages[0][3])
def test_two_succeeding_comments(self): buf = StringIO(""" # NOTE: one # NOTE: two msg = _(u'Foo Bar') """) messages = list(extract.extract_python(buf, ('_', ), ['NOTE:'], {})) self.assertEqual(u('Foo Bar'), messages[0][2]) self.assertEqual([u('NOTE: one'), u('NOTE: two')], messages[0][3])
def test_single_plural_form(self): buf = StringIO(r'''msgid "foo" msgid_plural "foos" msgstr[0] "Voh"''') catalog = pofile.read_po(buf, locale='ja_JP') self.assertEqual(1, len(catalog)) self.assertEqual(1, catalog.num_plurals) message = catalog['foo'] self.assertEqual(1, len(message.string))
def test_frontend_can_log_to_predefined_handler(self): custom_stream = StringIO() log = logging.getLogger('babel') log.addHandler(logging.StreamHandler(custom_stream)) self._run_init_catalog() self.assertNotEqual(id(sys.stderr), id(custom_stream)) self.assertEqual('', sys.stderr.getvalue()) assert len(custom_stream.getvalue()) > 0
def test_message_with_line_comment(self): buf = StringIO("""\ // NOTE: hello msg = _('Bonjour à tous') """) messages = list(extract.extract_javascript(buf, ('_', ), ['NOTE:'], {})) self.assertEqual(u('Bonjour \xe0 tous'), messages[0][2]) self.assertEqual([u('NOTE: hello')], messages[0][3])
def test_utf8_message(self): buf = StringIO(""" # NOTE: hello msg = _('Bonjour à tous') """) messages = list( extract.extract_python(buf, ('_', ), ['NOTE:'], {'encoding': 'utf-8'})) self.assertEqual(u('Bonjour \xe0 tous'), messages[0][2]) self.assertEqual([u('NOTE: hello')], messages[0][3])
def test_invalid_translator_comments3(self): buf = StringIO(""" # NOTE: Hi, # there! hithere = _('Hi there!') """) messages = list(extract.extract_python(buf, ('_', ), ['NOTE:'], {})) self.assertEqual(u('Hi there!'), messages[0][2]) self.assertEqual([], messages[0][3])
def test_comment_tag_multiline(self): buf = StringIO(""" # NOTE: A translation comment # with a second line msg = _(u'Foo Bar') """) messages = list(extract.extract_python(buf, ('_', ), ['NOTE:'], {})) self.assertEqual('Foo Bar', messages[0][2]) self.assertEqual(['NOTE: A translation comment', 'with a second line'], messages[0][3])
def test_invalid_translator_comments(self): buf = StringIO(""" # NOTE: this shouldn't apply to any messages hello = 'there' msg = _(u'Foo Bar') """) messages = list(extract.extract_python(buf, ('_', ), ['NOTE:'], {})) self.assertEqual(u('Foo Bar'), messages[0][2]) self.assertEqual([], messages[0][3])
def test_comment_tag_with_leading_space(self): buf = StringIO(""" #: A translation comment #: with leading spaces msg = _(u'Foo Bar') """) messages = list(extract.extract_python(buf, ('_', ), [':'], {})) self.assertEqual('Foo Bar', messages[0][2]) self.assertEqual([': A translation comment', ': with leading spaces'], messages[0][3])
def test_plural_with_square_brackets(self): buf = StringIO(r'''msgid "foo" msgid_plural "foos" msgstr[0] "Voh [text]" msgstr[1] "Vohs [text]"''') catalog = pofile.read_po(buf, locale='nb_NO') self.assertEqual(1, len(catalog)) self.assertEqual(2, catalog.num_plurals) message = catalog['foo'] self.assertEqual(2, len(message.string))
def test_nested_comments(self): buf = StringIO("""\ msg = ngettext('pylon', # TRANSLATORS: shouldn't be 'pylons', # TRANSLATORS: seeing this count) """) messages = list( extract.extract_python(buf, ('ngettext', ), ['TRANSLATORS:'], {})) self.assertEqual([(1, 'ngettext', (u('pylon'), u('pylons'), None), [])], messages)
def test_6_num_plurals_checkers(self): for _locale in [p for p in PLURALS if PLURALS[p][0] == 6]: po_file = r"""\ # %(english_name)s translations for TestProject. # Copyright (C) 2007 FooBar, Inc. # This file is distributed under the same license as the TestProject # project. # FIRST AUTHOR <EMAIL@ADDRESS>, 2007. # msgid "" msgstr "" "Project-Id-Version: TestProject 0.1\n" "Report-Msgid-Bugs-To: [email protected]\n" "POT-Creation-Date: 2007-04-01 15:30+0200\n" "PO-Revision-Date: %(date)s\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: %(locale)s <*****@*****.**>\n" "Plural-Forms: nplurals=%(num_plurals)s; plural=%(plural_expr)s\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel %(version)s\n" #. This will be a translator comment, #. that will include several lines #: project/file1.py:8 msgid "bar" msgstr "" #: project/file2.py:9 msgid "foobar" msgid_plural "foobars" msgstr[0] "" msgstr[1] "" msgstr[2] "" msgstr[3] "" msgstr[4] "" """ % dict(locale=_locale, english_name=Locale.parse(_locale).english_name, version=VERSION, year=time.strftime('%Y'), date=format_datetime(datetime.now(LOCALTZ), 'yyyy-MM-dd HH:mmZ', tzinfo=LOCALTZ, locale=_locale), num_plurals=PLURALS[_locale][0], plural_expr=PLURALS[_locale][0]) # This test will fail for revisions <= 406 because so far # catalog.num_plurals was neglected catalog = read_po(StringIO(po_file), _locale) message = catalog['foobar'] checkers.num_plurals(catalog, message)
def test_comment_tags_not_on_start_of_comment(self): buf = StringIO(""" # This shouldn't be in the output # because it didn't start with a comment tag # do NOTE: this will not be a translation comment # NOTE: This one will be msg = _(u'Foo Bar') """) messages = list(extract.extract_python(buf, ('_', ), ['NOTE:'], {})) self.assertEqual(u('Foo Bar'), messages[0][2]) self.assertEqual([u('NOTE: This one will be')], messages[0][3])
def test_silent_location_fallback(self): buf = StringIO('''\ #: broken_file.py msgid "missing line number" msgstr "" #: broken_file.py:broken_line_number msgid "broken line number" msgstr ""''') catalog = pofile.read_po(buf) self.assertEqual(catalog['missing line number'].locations, []) self.assertEqual(catalog['broken line number'].locations, [])
def test_multiline(self): buf = StringIO("""\ msg1 = ngettext('pylon', 'pylons', count) msg2 = ngettext('elvis', 'elvises', count) """) messages = list(extract.extract_python(buf, ('ngettext', ), [], {})) self.assertEqual([(1, 'ngettext', (u('pylon'), u('pylons'), None), []), (3, 'ngettext', (u('elvis'), u('elvises'), None), [])], messages)
def test_not_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. # ''') catalog = pofile.read_po(buf) self.assertEqual(1, len(list(catalog))) self.assertEqual(False, list(catalog)[0].fuzzy)
def test_simple_extract(self): buf = StringIO("""\ msg1 = _('simple') msg2 = gettext('simple') msg3 = ngettext('s', 'p', 42) """) messages = \ list(extract.extract('javascript', buf, extract.DEFAULT_KEYWORDS, [], {})) self.assertEqual([(1, 'simple', [], None), (2, 'simple', [], None), (3, ('s', 'p'), [], None)], messages)