Merge lp:~henninge/launchpad/bug-565294-devel into lp:launchpad

Proposed by Henning Eggers
Status: Merged
Approved by: Henning Eggers
Approved revision: no longer in the source branch.
Merged at revision: not available
Proposed branch: lp:~henninge/launchpad/bug-565294-devel
Merge into: lp:launchpad
Diff against target: 763 lines (+219/-89)
2 files modified
lib/lp/translations/model/pofile.py (+42/-23)
lib/lp/translations/tests/test_pofile.py (+177/-66)
To merge this branch: bzr merge lp:~henninge/launchpad/bug-565294-devel
Reviewer Review Type Date Requested Status
Michael Nelson (community) code Approve
Review via email: mp+24020@code.launchpad.net

Commit message

When exporting PO files, use the plural information from the imported file in some cases instead of the information from the language database.

Description of the change

Merging already approved branch into devel instead of production-devel.
https://code.edge.launchpad.net/~henninge/launchpad/bug-565294-nplurals

No changes since last approval. ;-)

To post a comment you must log in.
Revision history for this message
Michael Nelson (michael.nelson) wrote :
review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/lp/translations/model/pofile.py'
--- lib/lp/translations/model/pofile.py 2010-01-14 16:39:18 +0000
+++ lib/lp/translations/model/pofile.py 2010-04-26 10:23:30 +0000
@@ -34,7 +34,6 @@
34from canonical.launchpad.webapp.interfaces import (34from canonical.launchpad.webapp.interfaces import (
35 DEFAULT_FLAVOR, IStoreSelector, MAIN_STORE, MASTER_FLAVOR)35 DEFAULT_FLAVOR, IStoreSelector, MAIN_STORE, MASTER_FLAVOR)
36from canonical.launchpad.webapp.publisher import canonical_url36from canonical.launchpad.webapp.publisher import canonical_url
37from canonical.librarian.interfaces import ILibrarianClient
38from lp.registry.interfaces.person import validate_public_person37from lp.registry.interfaces.person import validate_public_person
39from lp.registry.model.person import Person38from lp.registry.model.person import Person
40from lp.translations.utilities.rosettastats import RosettaStats39from lp.translations.utilities.rosettastats import RosettaStats
@@ -792,7 +791,6 @@
792791
793 # A POT set has "new" suggestions if there is a non current792 # A POT set has "new" suggestions if there is a non current
794 # TranslationMessage newer than the current reviewed one.793 # TranslationMessage newer than the current reviewed one.
795 store = Store.of(self)
796 query = (794 query = (
797 """POTMsgSet.id IN (SELECT DISTINCT TranslationMessage.potmsgset795 """POTMsgSet.id IN (SELECT DISTINCT TranslationMessage.potmsgset
798 FROM TranslationMessage, TranslationTemplateItem, POTMsgSet796 FROM TranslationMessage, TranslationTemplateItem, POTMsgSet
@@ -1026,10 +1024,6 @@
1026 entry_to_import = removeSecurityProxy(entry_to_import)1024 entry_to_import = removeSecurityProxy(entry_to_import)
10271025
1028 translation_importer = getUtility(ITranslationImporter)1026 translation_importer = getUtility(ITranslationImporter)
1029 librarian_client = getUtility(ILibrarianClient)
1030
1031 import_file = librarian_client.getFileByAlias(
1032 entry_to_import.content.id)
10331027
1034 # While importing a file, there are two kinds of errors:1028 # While importing a file, there are two kinds of errors:
1035 #1029 #
@@ -1125,7 +1119,6 @@
1125 # There were some errors with translations.1119 # There were some errors with translations.
1126 errorsdetails = ''1120 errorsdetails = ''
1127 for error in errors:1121 for error in errors:
1128 pofile = error['pofile']
1129 potmsgset = error['potmsgset']1122 potmsgset = error['potmsgset']
1130 pomessage = error['pomessage']1123 pomessage = error['pomessage']
1131 error_message = error['error-message']1124 error_message = error['error-message']
@@ -1706,6 +1699,47 @@
17061699
1707 return self._pofile.language.code1700 return self._pofile.language.code
17081701
1702 def _isWesternPluralForm(self, number, expression):
1703 # Western style is nplurals=2;plural=n!=1.
1704 if number != 2:
1705 return False
1706 if expression is None:
1707 return False
1708 # Normalize: Remove spaces.
1709 expression = expression.replace(' ', '')
1710 # Normalize: Remove enclosing brackets.
1711 expression = expression.strip('()')
1712 return expression in ('n!=1', '1!=n', 'n>1', '1<n')
1713
1714 def _updateHeaderPluralInfo(self, header):
1715 header_nplurals = header.number_plural_forms
1716 database_nplurals = self._pofile.language.pluralforms
1717 # These checks are here to catch cases where the plural information
1718 # from the header might be more acurate than what we have in the
1719 # database. This is usually the case when the number of plural forms
1720 # has grown but not if it's the standard western form.
1721 # See bug 565294
1722 if header_nplurals is not None and database_nplurals is not None:
1723 if header_nplurals > database_nplurals:
1724 is_western = self._isWesternPluralForm(
1725 header_nplurals, header.plural_form_expression)
1726 if not is_western:
1727 # Use existing information from the header.
1728 return
1729 if database_nplurals is None:
1730 # In all other cases we never use the plural info from the header.
1731 header.number_plural_forms = None
1732 header.plural_form_expression = None
1733 else:
1734 # We have pluralforms information for this language so we
1735 # update the header to be sure that we use the language
1736 # information from our database instead of using the one
1737 # that we got from upstream. We check this information so
1738 # we are sure it's valid.
1739 header.number_plural_forms = self._pofile.language.pluralforms
1740 header.plural_form_expression = (
1741 self._pofile.language.pluralexpression)
1742
1709 @cachedproperty1743 @cachedproperty
1710 def header(self):1744 def header(self):
1711 """See `ITranslationFileData`."""1745 """See `ITranslationFileData`."""
@@ -1713,28 +1747,13 @@
1713 translation_header = self._pofile.getHeader()1747 translation_header = self._pofile.getHeader()
1714 # Update default fields based on its values in the template header.1748 # Update default fields based on its values in the template header.
1715 translation_header.updateFromTemplateHeader(template_header)1749 translation_header.updateFromTemplateHeader(template_header)
1716 date_reviewed = None
1717 translation_header.translation_revision_date = (1750 translation_header.translation_revision_date = (
1718 self._pofile.date_changed)1751 self._pofile.date_changed)
17191752
1720 translation_header.comment = self._pofile.topcomment1753 translation_header.comment = self._pofile.topcomment
17211754
1722 if self._pofile.potemplate.hasPluralMessage():1755 if self._pofile.potemplate.hasPluralMessage():
1723 number_plural_forms = None1756 self._updateHeaderPluralInfo(translation_header)
1724 plural_form_expression = None
1725 if self._pofile.language.pluralforms is not None:
1726 # We have pluralforms information for this language so we
1727 # update the header to be sure that we use the language
1728 # information from our database instead of use the one
1729 # that we got from upstream. We check this information so
1730 # we are sure it's valid.
1731 number_plural_forms = self._pofile.language.pluralforms
1732 plural_form_expression = (
1733 self._pofile.language.pluralexpression)
1734
1735 translation_header.number_plural_forms = number_plural_forms
1736 translation_header.plural_form_expression = plural_form_expression
1737
1738 if (self._pofile.lasttranslator is not None):1757 if (self._pofile.lasttranslator is not None):
1739 email = self._pofile.lasttranslator.safe_email_or_blank1758 email = self._pofile.lasttranslator.safe_email_or_blank
1740 if not email:1759 if not email:
17411760
=== modified file 'lib/lp/translations/tests/test_pofile.py'
--- lib/lp/translations/tests/test_pofile.py 2010-01-12 21:29:03 +0000
+++ lib/lp/translations/tests/test_pofile.py 2010-04-26 10:23:30 +0000
@@ -7,7 +7,8 @@
77
8from datetime import datetime, timedelta8from datetime import datetime, timedelta
9import pytz9import pytz
10import unittest10from textwrap import dedent
11from unittest import TestLoader
1112
12from zope.component import getAdapter, getUtility13from zope.component import getAdapter, getUtility
13from zope.security.proxy import removeSecurityProxy14from zope.security.proxy import removeSecurityProxy
@@ -93,7 +94,7 @@
93 self.assertEquals(found_potmsgsets, [plural_potmsgset])94 self.assertEquals(found_potmsgsets, [plural_potmsgset])
9495
95 # Search translations as well.96 # Search translations as well.
96 translation = self.factory.makeTranslationMessage(97 self.factory.makeTranslationMessage(
97 pofile=self.devel_sr_pofile, potmsgset=potmsgset,98 pofile=self.devel_sr_pofile, potmsgset=potmsgset,
98 translations=[u"One translation message"])99 translations=[u"One translation message"])
99 found_potmsgsets = list(100 found_potmsgsets = list(
@@ -101,7 +102,7 @@
101 self.assertEquals(found_potmsgsets, [potmsgset])102 self.assertEquals(found_potmsgsets, [potmsgset])
102103
103 # Search matches all plural forms.104 # Search matches all plural forms.
104 plural_translation = self.factory.makeTranslationMessage(105 self.factory.makeTranslationMessage(
105 pofile=self.devel_sr_pofile, potmsgset=plural_potmsgset,106 pofile=self.devel_sr_pofile, potmsgset=plural_potmsgset,
106 translations=[u"One translation message",107 translations=[u"One translation message",
107 u"Plural translation message",108 u"Plural translation message",
@@ -153,7 +154,7 @@
153 # If somebody else provides a translation, it's not added to the154 # If somebody else provides a translation, it's not added to the
154 # list of submitter's translations.155 # list of submitter's translations.
155 someone_else = self.factory.makePerson()156 someone_else = self.factory.makePerson()
156 other_translation = self.factory.makeTranslationMessage(157 self.factory.makeTranslationMessage(
157 pofile=self.devel_sr_pofile, potmsgset=potmsgset,158 pofile=self.devel_sr_pofile, potmsgset=potmsgset,
158 translations=[u"Another translation"],159 translations=[u"Another translation"],
159 translator=someone_else)160 translator=someone_else)
@@ -166,7 +167,7 @@
166 # to the list of submitter's translations for *former* POFile.167 # to the list of submitter's translations for *former* POFile.
167 self.devel_sr_latin_pofile = self.factory.makePOFile(168 self.devel_sr_latin_pofile = self.factory.makePOFile(
168 'sr', variant=u'latin', potemplate=self.devel_potemplate)169 'sr', variant=u'latin', potemplate=self.devel_potemplate)
169 latin_translation = self.factory.makeTranslationMessage(170 self.factory.makeTranslationMessage(
170 pofile=self.devel_sr_latin_pofile, potmsgset=potmsgset,171 pofile=self.devel_sr_latin_pofile, potmsgset=potmsgset,
171 translations=[u"Yet another translation"],172 translations=[u"Yet another translation"],
172 translator=submitter)173 translator=submitter)
@@ -194,7 +195,7 @@
194 self.assertEquals(found_translations, [])195 self.assertEquals(found_translations, [])
195196
196 # When a diverged translation is added, the potmsgset is returned.197 # When a diverged translation is added, the potmsgset is returned.
197 translation = self.factory.makeTranslationMessage(198 self.factory.makeTranslationMessage(
198 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,199 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,
199 translations=[u"Translation"])200 translations=[u"Translation"])
200 found_translations = list(201 found_translations = list(
@@ -202,7 +203,7 @@
202 self.assertEquals(found_translations, [self.potmsgset])203 self.assertEquals(found_translations, [self.potmsgset])
203204
204 # If diverged translation is empty, POTMsgSet is not listed.205 # If diverged translation is empty, POTMsgSet is not listed.
205 translation = self.factory.makeTranslationMessage(206 self.factory.makeTranslationMessage(
206 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,207 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,
207 translations=[u""])208 translations=[u""])
208 found_translations = list(209 found_translations = list(
@@ -214,7 +215,7 @@
214 # translation for the POTMsgSet as well.215 # translation for the POTMsgSet as well.
215216
216 # We create a shared translation first.217 # We create a shared translation first.
217 shared_translation = self.factory.makeSharedTranslationMessage(218 self.factory.makeSharedTranslationMessage(
218 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,219 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,
219 translations=[u"Shared translation"])220 translations=[u"Shared translation"])
220221
@@ -224,7 +225,7 @@
224 self.assertEquals(found_translations, [self.potmsgset])225 self.assertEquals(found_translations, [self.potmsgset])
225226
226 # When an empty diverged translation is added, nothing is listed.227 # When an empty diverged translation is added, nothing is listed.
227 translation = self.factory.makeTranslationMessage(228 self.factory.makeTranslationMessage(
228 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,229 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,
229 translations=[u""])230 translations=[u""])
230 found_translations = list(231 found_translations = list(
@@ -232,7 +233,7 @@
232 self.assertEquals(found_translations, [])233 self.assertEquals(found_translations, [])
233234
234 # If diverged translation is non-empty, POTMsgSet is listed.235 # If diverged translation is non-empty, POTMsgSet is listed.
235 translation = self.factory.makeTranslationMessage(236 self.factory.makeTranslationMessage(
236 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,237 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,
237 translations=[u"Translation"])238 translations=[u"Translation"])
238 found_translations = list(239 found_translations = list(
@@ -244,7 +245,7 @@
244 # empty shared translation for the POTMsgSet as well.245 # empty shared translation for the POTMsgSet as well.
245246
246 # We create an empty shared translation first.247 # We create an empty shared translation first.
247 shared_translation = self.factory.makeSharedTranslationMessage(248 self.factory.makeSharedTranslationMessage(
248 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,249 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,
249 translations=[u""])250 translations=[u""])
250251
@@ -255,7 +256,7 @@
255 self.assertEquals(found_translations, [])256 self.assertEquals(found_translations, [])
256257
257 # When an empty diverged translation is added, nothing is listed.258 # When an empty diverged translation is added, nothing is listed.
258 translation = self.factory.makeTranslationMessage(259 self.factory.makeTranslationMessage(
259 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,260 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,
260 translations=[u""])261 translations=[u""])
261 found_translations = list(262 found_translations = list(
@@ -263,7 +264,7 @@
263 self.assertEquals(found_translations, [])264 self.assertEquals(found_translations, [])
264265
265 # If diverged translation is non-empty, POTMsgSet is listed.266 # If diverged translation is non-empty, POTMsgSet is listed.
266 translation = self.factory.makeTranslationMessage(267 self.factory.makeTranslationMessage(
267 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,268 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,
268 translations=[u"Translation"])269 translations=[u"Translation"])
269 found_translations = list(270 found_translations = list(
@@ -275,7 +276,7 @@
275 # translated message.276 # translated message.
276277
277 # Add a diverged translation on the included POTMsgSet...278 # Add a diverged translation on the included POTMsgSet...
278 translation = self.factory.makeTranslationMessage(279 self.factory.makeTranslationMessage(
279 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,280 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,
280 translations=[u"Diverged translation"])281 translations=[u"Diverged translation"])
281282
@@ -284,7 +285,7 @@
284 u"Translated text")285 u"Translated text")
285 potmsgset.setSequence(self.devel_potemplate, 2)286 potmsgset.setSequence(self.devel_potemplate, 2)
286287
287 shared_translation = self.factory.makeSharedTranslationMessage(288 self.factory.makeSharedTranslationMessage(
288 pofile=self.devel_sr_pofile, potmsgset=potmsgset,289 pofile=self.devel_sr_pofile, potmsgset=potmsgset,
289 translations=[u"Shared translation"])290 translations=[u"Shared translation"])
290291
@@ -303,7 +304,7 @@
303 self.assertEquals(found_translations, [self.potmsgset])304 self.assertEquals(found_translations, [self.potmsgset])
304305
305 # When a diverged translation is added, the potmsgset is returned.306 # When a diverged translation is added, the potmsgset is returned.
306 translation = self.factory.makeTranslationMessage(307 self.factory.makeTranslationMessage(
307 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,308 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,
308 translations=[u"Translation"])309 translations=[u"Translation"])
309 found_translations = list(310 found_translations = list(
@@ -311,7 +312,7 @@
311 self.assertEquals(found_translations, [])312 self.assertEquals(found_translations, [])
312313
313 # If diverged translation is empty, POTMsgSet is not listed.314 # If diverged translation is empty, POTMsgSet is not listed.
314 translation = self.factory.makeTranslationMessage(315 self.factory.makeTranslationMessage(
315 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,316 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,
316 translations=[u""])317 translations=[u""])
317 found_translations = list(318 found_translations = list(
@@ -323,7 +324,7 @@
323 # translation for the POTMsgSet as well.324 # translation for the POTMsgSet as well.
324325
325 # We create a shared translation first.326 # We create a shared translation first.
326 shared_translation = self.factory.makeSharedTranslationMessage(327 self.factory.makeSharedTranslationMessage(
327 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,328 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,
328 translations=[u"Shared translation"])329 translations=[u"Shared translation"])
329330
@@ -333,7 +334,7 @@
333 self.assertEquals(found_translations, [])334 self.assertEquals(found_translations, [])
334335
335 # When an empty diverged translation is added, nothing is listed.336 # When an empty diverged translation is added, nothing is listed.
336 translation = self.factory.makeTranslationMessage(337 self.factory.makeTranslationMessage(
337 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,338 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,
338 translations=[u""])339 translations=[u""])
339 found_translations = list(340 found_translations = list(
@@ -341,7 +342,7 @@
341 self.assertEquals(found_translations, [self.potmsgset])342 self.assertEquals(found_translations, [self.potmsgset])
342343
343 # If diverged translation is non-empty, POTMsgSet is listed.344 # If diverged translation is non-empty, POTMsgSet is listed.
344 translation = self.factory.makeTranslationMessage(345 self.factory.makeTranslationMessage(
345 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,346 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,
346 translations=[u"Translation"])347 translations=[u"Translation"])
347 found_translations = list(348 found_translations = list(
@@ -353,7 +354,7 @@
353 # empty shared translation for the POTMsgSet as well.354 # empty shared translation for the POTMsgSet as well.
354355
355 # We create an empty shared translation first.356 # We create an empty shared translation first.
356 shared_translation = self.factory.makeSharedTranslationMessage(357 self.factory.makeSharedTranslationMessage(
357 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,358 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,
358 translations=[u""])359 translations=[u""])
359360
@@ -364,7 +365,7 @@
364 self.assertEquals(found_translations, [self.potmsgset])365 self.assertEquals(found_translations, [self.potmsgset])
365366
366 # When an empty diverged translation is added, nothing is listed.367 # When an empty diverged translation is added, nothing is listed.
367 translation = self.factory.makeTranslationMessage(368 self.factory.makeTranslationMessage(
368 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,369 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,
369 translations=[u""])370 translations=[u""])
370 found_translations = list(371 found_translations = list(
@@ -372,7 +373,7 @@
372 self.assertEquals(found_translations, [self.potmsgset])373 self.assertEquals(found_translations, [self.potmsgset])
373374
374 # If diverged translation is non-empty, POTMsgSet is listed.375 # If diverged translation is non-empty, POTMsgSet is listed.
375 translation = self.factory.makeTranslationMessage(376 self.factory.makeTranslationMessage(
376 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,377 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,
377 translations=[u"Translation"])378 translations=[u"Translation"])
378 found_translations = list(379 found_translations = list(
@@ -384,7 +385,7 @@
384 # untranslated message.385 # untranslated message.
385386
386 # Add an empty translation to the included POTMsgSet...387 # Add an empty translation to the included POTMsgSet...
387 translation = self.factory.makeTranslationMessage(388 self.factory.makeTranslationMessage(
388 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,389 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,
389 translations=[u""])390 translations=[u""])
390391
@@ -478,14 +479,14 @@
478479
479 # A POTMsgSet has a shared, current translation created 5 days ago.480 # A POTMsgSet has a shared, current translation created 5 days ago.
480 date_created = datetime.now(pytz.UTC)-timedelta(5)481 date_created = datetime.now(pytz.UTC)-timedelta(5)
481 translation = self.factory.makeSharedTranslationMessage(482 self.factory.makeSharedTranslationMessage(
482 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,483 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,
483 translations=[u"Shared translation"], date_updated=date_created)484 translations=[u"Shared translation"], date_updated=date_created)
484485
485 # And we also have a diverged translation created a day after shared486 # And we also have a diverged translation created a day after shared
486 # current translation.487 # current translation.
487 diverged_date = date_created + timedelta(1)488 diverged_date = date_created + timedelta(1)
488 translation = self.factory.makeTranslationMessage(489 self.factory.makeTranslationMessage(
489 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,490 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,
490 translations=[u"Old translation"], date_updated=diverged_date)491 translations=[u"Old translation"], date_updated=diverged_date)
491492
@@ -536,7 +537,7 @@
536 # Test that multiple unreviewed POTMsgSets are returned.537 # Test that multiple unreviewed POTMsgSets are returned.
537538
538 # One POTMsgSet has no translations, but only a suggestion.539 # One POTMsgSet has no translations, but only a suggestion.
539 translation = self.factory.makeTranslationMessage(540 self.factory.makeTranslationMessage(
540 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,541 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,
541 translations=[u"New suggestion"], suggestion=True)542 translations=[u"New suggestion"], suggestion=True)
542543
@@ -545,11 +546,11 @@
545 u"Translated text")546 u"Translated text")
546 potmsgset.setSequence(self.devel_potemplate, 2)547 potmsgset.setSequence(self.devel_potemplate, 2)
547 date_created = datetime.now(pytz.UTC) - timedelta(5)548 date_created = datetime.now(pytz.UTC) - timedelta(5)
548 translation = self.factory.makeTranslationMessage(549 self.factory.makeTranslationMessage(
549 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,550 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,
550 translations=[u"Translation"], date_updated=date_created)551 translations=[u"Translation"], date_updated=date_created)
551 suggestion_date = date_created + timedelta(1)552 suggestion_date = date_created + timedelta(1)
552 translation = self.factory.makeTranslationMessage(553 self.factory.makeTranslationMessage(
553 pofile=self.devel_sr_pofile, potmsgset=potmsgset,554 pofile=self.devel_sr_pofile, potmsgset=potmsgset,
554 translations=[u"New suggestion"], suggestion=True,555 translations=[u"New suggestion"], suggestion=True,
555 date_updated=suggestion_date)556 date_updated=suggestion_date)
@@ -562,12 +563,12 @@
562 def test_getPOTMsgSetWithNewSuggestions_distinct(self):563 def test_getPOTMsgSetWithNewSuggestions_distinct(self):
563 # Provide two suggestions on a single message and make sure564 # Provide two suggestions on a single message and make sure
564 # a POTMsgSet is returned only once.565 # a POTMsgSet is returned only once.
565 translation1 = self.factory.makeSharedTranslationMessage(566 self.factory.makeSharedTranslationMessage(
566 pofile=self.devel_sr_pofile,567 pofile=self.devel_sr_pofile,
567 potmsgset=self.potmsgset,568 potmsgset=self.potmsgset,
568 translations=["A suggestion"],569 translations=["A suggestion"],
569 suggestion=True)570 suggestion=True)
570 translation2 = self.factory.makeSharedTranslationMessage(571 self.factory.makeSharedTranslationMessage(
571 pofile=self.devel_sr_pofile,572 pofile=self.devel_sr_pofile,
572 potmsgset=self.potmsgset,573 potmsgset=self.potmsgset,
573 translations=["Another suggestion"],574 translations=["Another suggestion"],
@@ -646,7 +647,6 @@
646647
647 # But adding a diverged current and imported translation means648 # But adding a diverged current and imported translation means
648 # that it's not changed anymore.649 # that it's not changed anymore.
649 old_translation = translation
650 translation = self.factory.makeTranslationMessage(650 translation = self.factory.makeTranslationMessage(
651 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,651 pofile=self.devel_sr_pofile, potmsgset=self.potmsgset,
652 translations=[u"Diverged imported"], is_imported=True,652 translations=[u"Diverged imported"], is_imported=True,
@@ -753,42 +753,42 @@
753 # Second POTMsgSet is untranslated, but with a suggestion.753 # Second POTMsgSet is untranslated, but with a suggestion.
754 potmsgset = self.factory.makePOTMsgSet(self.devel_potemplate)754 potmsgset = self.factory.makePOTMsgSet(self.devel_potemplate)
755 potmsgset.setSequence(self.devel_potemplate, 2)755 potmsgset.setSequence(self.devel_potemplate, 2)
756 translation = self.factory.makeTranslationMessage(756 self.factory.makeTranslationMessage(
757 pofile=self.devel_sr_pofile, potmsgset=potmsgset,757 pofile=self.devel_sr_pofile, potmsgset=potmsgset,
758 translations=[u"Unreviewed suggestion"], suggestion=True)758 translations=[u"Unreviewed suggestion"], suggestion=True)
759759
760 # Third POTMsgSet is translated, and with a suggestion.760 # Third POTMsgSet is translated, and with a suggestion.
761 potmsgset = self.factory.makePOTMsgSet(self.devel_potemplate)761 potmsgset = self.factory.makePOTMsgSet(self.devel_potemplate)
762 potmsgset.setSequence(self.devel_potemplate, 3)762 potmsgset.setSequence(self.devel_potemplate, 3)
763 translation = self.factory.makeTranslationMessage(763 self.factory.makeTranslationMessage(
764 pofile=self.devel_sr_pofile, potmsgset=potmsgset,764 pofile=self.devel_sr_pofile, potmsgset=potmsgset,
765 translations=[u"Translation"], suggestion=False,765 translations=[u"Translation"], suggestion=False,
766 date_updated=datetime.now(pytz.UTC)-timedelta(1))766 date_updated=datetime.now(pytz.UTC)-timedelta(1))
767 translation = self.factory.makeTranslationMessage(767 self.factory.makeTranslationMessage(
768 pofile=self.devel_sr_pofile, potmsgset=potmsgset,768 pofile=self.devel_sr_pofile, potmsgset=potmsgset,
769 translations=[u"Another suggestion"], suggestion=True)769 translations=[u"Another suggestion"], suggestion=True)
770770
771 # Fourth POTMsgSet is translated in import.771 # Fourth POTMsgSet is translated in import.
772 potmsgset = self.factory.makePOTMsgSet(self.devel_potemplate)772 potmsgset = self.factory.makePOTMsgSet(self.devel_potemplate)
773 potmsgset.setSequence(self.devel_potemplate, 4)773 potmsgset.setSequence(self.devel_potemplate, 4)
774 translation = self.factory.makeTranslationMessage(774 self.factory.makeTranslationMessage(
775 pofile=self.devel_sr_pofile, potmsgset=potmsgset,775 pofile=self.devel_sr_pofile, potmsgset=potmsgset,
776 translations=[u"Imported translation"], is_imported=True)776 translations=[u"Imported translation"], is_imported=True)
777777
778 # Fifth POTMsgSet is translated in import, but changed in LP.778 # Fifth POTMsgSet is translated in import, but changed in LP.
779 potmsgset = self.factory.makePOTMsgSet(self.devel_potemplate)779 potmsgset = self.factory.makePOTMsgSet(self.devel_potemplate)
780 potmsgset.setSequence(self.devel_potemplate, 5)780 potmsgset.setSequence(self.devel_potemplate, 5)
781 translation = self.factory.makeTranslationMessage(781 self.factory.makeTranslationMessage(
782 pofile=self.devel_sr_pofile, potmsgset=potmsgset,782 pofile=self.devel_sr_pofile, potmsgset=potmsgset,
783 translations=[u"Imported translation"], is_imported=True)783 translations=[u"Imported translation"], is_imported=True)
784 translation = self.factory.makeTranslationMessage(784 self.factory.makeTranslationMessage(
785 pofile=self.devel_sr_pofile, potmsgset=potmsgset,785 pofile=self.devel_sr_pofile, potmsgset=potmsgset,
786 translations=[u"LP translation"], is_imported=False)786 translations=[u"LP translation"], is_imported=False)
787787
788 # Sixth POTMsgSet is translated in LP only.788 # Sixth POTMsgSet is translated in LP only.
789 potmsgset = self.factory.makePOTMsgSet(self.devel_potemplate)789 potmsgset = self.factory.makePOTMsgSet(self.devel_potemplate)
790 potmsgset.setSequence(self.devel_potemplate, 6)790 potmsgset.setSequence(self.devel_potemplate, 6)
791 translation = self.factory.makeTranslationMessage(791 self.factory.makeTranslationMessage(
792 pofile=self.devel_sr_pofile, potmsgset=potmsgset,792 pofile=self.devel_sr_pofile, potmsgset=potmsgset,
793 translations=[u"New translation"], is_imported=False)793 translations=[u"New translation"], is_imported=False)
794794
@@ -810,7 +810,7 @@
810 def test_TranslationFileData_adapter(self):810 def test_TranslationFileData_adapter(self):
811 # Test that exporting works correctly with shared and diverged811 # Test that exporting works correctly with shared and diverged
812 # messages.812 # messages.
813 shared_translation = self.factory.makeSharedTranslationMessage(813 self.factory.makeSharedTranslationMessage(
814 pofile=self.devel_sr_pofile,814 pofile=self.devel_sr_pofile,
815 potmsgset=self.potmsgset,815 potmsgset=self.potmsgset,
816 translations=["Shared translation"])816 translations=["Shared translation"])
@@ -827,7 +827,7 @@
827 "Shared translation")])827 "Shared translation")])
828828
829 # When we add a diverged translation, only that is exported.829 # When we add a diverged translation, only that is exported.
830 diverged_translation = self.factory.makeTranslationMessage(830 self.factory.makeTranslationMessage(
831 pofile=self.devel_sr_pofile,831 pofile=self.devel_sr_pofile,
832 potmsgset=self.potmsgset,832 potmsgset=self.potmsgset,
833 translations=["Diverged translation"],833 translations=["Diverged translation"],
@@ -887,7 +887,7 @@
887 productseries=self.foo_stable, name="template-2")887 productseries=self.foo_stable, name="template-2")
888888
889 self.assertEqual(None, potemplate_devel_1.getPOFileByLang('eo'))889 self.assertEqual(None, potemplate_devel_1.getPOFileByLang('eo'))
890 pofile_devel = potemplate_devel_1.newPOFile('eo')890 potemplate_devel_1.newPOFile('eo')
891 self.assertEqual(None, potemplate_stable_2.getPOFileByLang('eo'))891 self.assertEqual(None, potemplate_stable_2.getPOFileByLang('eo'))
892892
893 def test_potemplate_creation(self):893 def test_potemplate_creation(self):
@@ -895,14 +895,14 @@
895 # all shared potemplates.895 # all shared potemplates.
896 foo_other = self.factory.makeProductSeries(896 foo_other = self.factory.makeProductSeries(
897 name='other', product=self.foo)897 name='other', product=self.foo)
898 other_potemplate = self.factory.makePOTemplate(898 self.factory.makePOTemplate(
899 productseries=foo_other, name="messages")899 productseries=foo_other, name="messages")
900 devel_potemplate = self.factory.makePOTemplate(900 devel_potemplate = self.factory.makePOTemplate(
901 productseries=self.foo_devel, name="messages")901 productseries=self.foo_devel, name="messages")
902 # These will automatically be shared across all sharing templates.902 # These will automatically be shared across all sharing templates.
903 # They will also be created in the 'other' series.903 # They will also be created in the 'other' series.
904 pofile_devel_eo = devel_potemplate.newPOFile('eo')904 devel_potemplate.newPOFile('eo')
905 pofile_devel_de = devel_potemplate.newPOFile('de')905 devel_potemplate.newPOFile('de')
906906
907 stable_potemplate = self.factory.makePOTemplate(907 stable_potemplate = self.factory.makePOTemplate(
908 productseries=self.foo_stable, name="messages")908 productseries=self.foo_stable, name="messages")
@@ -1015,11 +1015,11 @@
1015 def test_getPOTMsgSetTranslated_ordering(self):1015 def test_getPOTMsgSetTranslated_ordering(self):
1016 # Translate both POTMsgSets in devel_sr_pofile, so1016 # Translate both POTMsgSets in devel_sr_pofile, so
1017 # they are returned with getPOTMsgSetTranslated() call.1017 # they are returned with getPOTMsgSetTranslated() call.
1018 translation1 = self.factory.makeSharedTranslationMessage(1018 self.factory.makeSharedTranslationMessage(
1019 pofile=self.devel_sr_pofile,1019 pofile=self.devel_sr_pofile,
1020 potmsgset=self.potmsgset1,1020 potmsgset=self.potmsgset1,
1021 translations=["Shared translation"])1021 translations=["Shared translation"])
1022 translation2 = self.factory.makeSharedTranslationMessage(1022 self.factory.makeSharedTranslationMessage(
1023 pofile=self.devel_sr_pofile,1023 pofile=self.devel_sr_pofile,
1024 potmsgset=self.potmsgset2,1024 potmsgset=self.potmsgset2,
1025 translations=["Another shared translation"])1025 translations=["Another shared translation"])
@@ -1073,22 +1073,22 @@
1073 def test_getPOTMsgSetChangedInLaunchpad_ordering(self):1073 def test_getPOTMsgSetChangedInLaunchpad_ordering(self):
1074 # Suggest a translation on both POTMsgSets in devel_sr_pofile,1074 # Suggest a translation on both POTMsgSets in devel_sr_pofile,
1075 # so they are returned with getPOTMsgSetWithNewSuggestions() call.1075 # so they are returned with getPOTMsgSetWithNewSuggestions() call.
1076 imported1 = self.factory.makeSharedTranslationMessage(1076 self.factory.makeSharedTranslationMessage(
1077 pofile=self.devel_sr_pofile,1077 pofile=self.devel_sr_pofile,
1078 potmsgset=self.potmsgset1,1078 potmsgset=self.potmsgset1,
1079 translations=["Imported"],1079 translations=["Imported"],
1080 is_imported=True)1080 is_imported=True)
1081 translation1 = self.factory.makeSharedTranslationMessage(1081 self.factory.makeSharedTranslationMessage(
1082 pofile=self.devel_sr_pofile,1082 pofile=self.devel_sr_pofile,
1083 potmsgset=self.potmsgset1,1083 potmsgset=self.potmsgset1,
1084 translations=["Changed"],1084 translations=["Changed"],
1085 is_imported=False)1085 is_imported=False)
1086 imported2 = self.factory.makeSharedTranslationMessage(1086 self.factory.makeSharedTranslationMessage(
1087 pofile=self.devel_sr_pofile,1087 pofile=self.devel_sr_pofile,
1088 potmsgset=self.potmsgset2,1088 potmsgset=self.potmsgset2,
1089 translations=["Another imported"],1089 translations=["Another imported"],
1090 is_imported=True)1090 is_imported=True)
1091 translation2 = self.factory.makeSharedTranslationMessage(1091 self.factory.makeSharedTranslationMessage(
1092 pofile=self.devel_sr_pofile,1092 pofile=self.devel_sr_pofile,
1093 potmsgset=self.potmsgset2,1093 potmsgset=self.potmsgset2,
1094 translations=["Another changed"],1094 translations=["Another changed"],
@@ -1186,11 +1186,11 @@
1186 # This test will go away when potmsgset.sequence goes away.1186 # This test will go away when potmsgset.sequence goes away.
11871187
1188 # Give the method something to search for.1188 # Give the method something to search for.
1189 translation1 = self.factory.makeSharedTranslationMessage(1189 self.factory.makeSharedTranslationMessage(
1190 pofile=self.devel_sr_pofile,1190 pofile=self.devel_sr_pofile,
1191 potmsgset=self.potmsgset1,1191 potmsgset=self.potmsgset1,
1192 translations=["Shared translation"])1192 translations=["Shared translation"])
1193 translation2 = self.factory.makeSharedTranslationMessage(1193 self.factory.makeSharedTranslationMessage(
1194 pofile=self.devel_sr_pofile,1194 pofile=self.devel_sr_pofile,
1195 potmsgset=self.potmsgset2,1195 potmsgset=self.potmsgset2,
1196 translations=["Another shared translation"])1196 translations=["Another shared translation"])
@@ -1410,7 +1410,7 @@
1410 # All POFiles with translation credits messages are1410 # All POFiles with translation credits messages are
1411 # returned along with relevant POTMsgSets.1411 # returned along with relevant POTMsgSets.
1412 potemplate1 = self.factory.makePOTemplate()1412 potemplate1 = self.factory.makePOTemplate()
1413 credits_potmsgset = self.factory.makePOTMsgSet(1413 self.factory.makePOTMsgSet(
1414 potemplate1, singular=u'translator-credits', sequence=1)1414 potemplate1, singular=u'translator-credits', sequence=1)
14151415
1416 sr_pofile = self.factory.makePOFile('sr', potemplate=potemplate1)1416 sr_pofile = self.factory.makePOFile('sr', potemplate=potemplate1)
@@ -1430,7 +1430,7 @@
1430 # If another POTemplate has a translation credits message, it's1430 # If another POTemplate has a translation credits message, it's
1431 # returned as well.1431 # returned as well.
1432 potemplate2 = self.factory.makePOTemplate()1432 potemplate2 = self.factory.makePOTemplate()
1433 kde_credits_potmsgset = self.factory.makePOTMsgSet(1433 self.factory.makePOTMsgSet(
1434 potemplate2, singular=u'Your names',1434 potemplate2, singular=u'Your names',
1435 context=u'NAME OF TRANSLATORS', sequence=1)1435 context=u'NAME OF TRANSLATORS', sequence=1)
1436 sr_kde_pofile = self.factory.makePOFile('sr', potemplate=potemplate2)1436 sr_kde_pofile = self.factory.makePOFile('sr', potemplate=potemplate2)
@@ -1493,7 +1493,7 @@
1493 def test_getPOFilesByPathAndOrigin_path_mismatch(self):1493 def test_getPOFilesByPathAndOrigin_path_mismatch(self):
1494 # getPOFilesByPathAndOrigin matches on POFile path.1494 # getPOFilesByPathAndOrigin matches on POFile path.
1495 template = self.factory.makePOTemplate()1495 template = self.factory.makePOTemplate()
1496 pofile = template.newPOFile('ta')1496 template.newPOFile('ta')
14971497
1498 not_found = self.pofileset.getPOFilesByPathAndOrigin(1498 not_found = self.pofileset.getPOFilesByPathAndOrigin(
1499 'tu.po', distroseries=template.distroseries,1499 'tu.po', distroseries=template.distroseries,
@@ -1613,7 +1613,7 @@
1613 self.assertEquals(self.pofile.currentCount(), 0)1613 self.assertEquals(self.pofile.currentCount(), 0)
16141614
1615 # Adding an imported translation increases currentCount().1615 # Adding an imported translation increases currentCount().
1616 imported = self.factory.makeTranslationMessage(1616 self.factory.makeTranslationMessage(
1617 pofile=self.pofile,1617 pofile=self.pofile,
1618 potmsgset=self.potmsgset,1618 potmsgset=self.potmsgset,
1619 translations=["Imported current"],1619 translations=["Imported current"],
@@ -1624,7 +1624,7 @@
1624 # Adding a suggestion (i.e. unused translation)1624 # Adding a suggestion (i.e. unused translation)
1625 # will not change the current count when there's1625 # will not change the current count when there's
1626 # already an imported message.1626 # already an imported message.
1627 suggestion = self.factory.makeTranslationMessage(1627 self.factory.makeTranslationMessage(
1628 pofile=self.pofile,1628 pofile=self.pofile,
1629 potmsgset=self.potmsgset,1629 potmsgset=self.potmsgset,
1630 translations=["A suggestion"],1630 translations=["A suggestion"],
@@ -1640,7 +1640,7 @@
16401640
1641 # Adding a current translation for an untranslated1641 # Adding a current translation for an untranslated
1642 # message increases the count of new translations in LP.1642 # message increases the count of new translations in LP.
1643 current = self.factory.makeTranslationMessage(1643 self.factory.makeTranslationMessage(
1644 pofile=self.pofile,1644 pofile=self.pofile,
1645 potmsgset=self.potmsgset,1645 potmsgset=self.potmsgset,
1646 translations=["Current"])1646 translations=["Current"])
@@ -1651,12 +1651,12 @@
1651 # If we get an 'imported' translation for what1651 # If we get an 'imported' translation for what
1652 # we already have as 'new', it's not considered 'new'1652 # we already have as 'new', it's not considered 'new'
1653 # anymore since it has been synced.1653 # anymore since it has been synced.
1654 current = self.factory.makeTranslationMessage(1654 self.factory.makeTranslationMessage(
1655 pofile=self.pofile,1655 pofile=self.pofile,
1656 potmsgset=self.potmsgset,1656 potmsgset=self.potmsgset,
1657 translations=["Current"])1657 translations=["Current"])
1658 # Reimport it but with is_imported=True.1658 # Reimport it but with is_imported=True.
1659 imported = self.factory.makeTranslationMessage(1659 self.factory.makeTranslationMessage(
1660 pofile=self.pofile,1660 pofile=self.pofile,
1661 potmsgset=self.potmsgset,1661 potmsgset=self.potmsgset,
1662 translations=["Current"],1662 translations=["Current"],
@@ -1669,12 +1669,12 @@
1669 # If we change an 'imported' translation through1669 # If we change an 'imported' translation through
1670 # Launchpad, it's still not considered 'new',1670 # Launchpad, it's still not considered 'new',
1671 # but an 'update' instead.1671 # but an 'update' instead.
1672 imported = self.factory.makeTranslationMessage(1672 self.factory.makeTranslationMessage(
1673 pofile=self.pofile,1673 pofile=self.pofile,
1674 potmsgset=self.potmsgset,1674 potmsgset=self.potmsgset,
1675 translations=["Imported"],1675 translations=["Imported"],
1676 is_imported=True)1676 is_imported=True)
1677 update = self.factory.makeTranslationMessage(1677 self.factory.makeTranslationMessage(
1678 pofile=self.pofile,1678 pofile=self.pofile,
1679 potmsgset=self.potmsgset,1679 potmsgset=self.potmsgset,
1680 translations=["Changed"])1680 translations=["Changed"])
@@ -1722,8 +1722,7 @@
17221722
1723 def test_getTranslationRows_sequence(self):1723 def test_getTranslationRows_sequence(self):
1724 # Test for correct sorting of obsolete messages (where sequence=0).1724 # Test for correct sorting of obsolete messages (where sequence=0).
1725 msgsets = [1725 [self._createMessageSet(msg) for msg in self.TEST_MESSAGES]
1726 self._createMessageSet(msg) for msg in self.TEST_MESSAGES]
1727 for rownum, row in enumerate(1726 for rownum, row in enumerate(
1728 self.pofile.getTranslationRows()):1727 self.pofile.getTranslationRows()):
1729 self.failUnlessEqual(1728 self.failUnlessEqual(
@@ -1732,5 +1731,117 @@
1732 "(sequence=0) to the end of the file.")1731 "(sequence=0) to the end of the file.")
17331732
17341733
1734class TestPOFileToTranslationFileDataAdapter(TestCaseWithFactory):
1735 """Test POFile being adapted to IPOFileToTranslationFileData."""
1736
1737 layer = ZopelessDatabaseLayer
1738
1739 header = dedent("""
1740 Project-Id-Version: foo
1741 Report-Msgid-Bugs-To:
1742 POT-Creation-Date: 2007-07-09 03:39+0100
1743 PO-Revision-Date: 2001-09-09 01:46+0000
1744 Last-Translator: Kubla Kahn <kk@pleasure-dome.com>
1745 Language-Team: Serbian <sr@li.org>
1746 MIME-Version: 1.0
1747 Content-Type: text/plain; charset=UTF-8
1748 Content-Transfer-Encoding: 8bit
1749 Plural-Forms: %s""")
1750
1751 western_plural = "nplurals=2; plural=(n != 1)"
1752 other_2_plural = "nplurals=2; plural=(n > 0)"
1753 generic_plural = "nplurals=INTEGER; plural=EXPRESSION"
1754 serbian3_plural = ("nplurals=3; plural=(n%10==1 && n%100!=11 "
1755 "? 0 : n%10>=2 && n%10<=4 && (n% 100<10 || n%100>=20) "
1756 "? 1 : 2)")
1757 serbian4_plural = ("nplurals=4; plural=(n==1 ? 3 : (n%10==1 && n%100!=11 "
1758 "? 0 : n%10>=2 && n%10<=4 && (n% 100<10 || n%100>=20) "
1759 "? 1 : 2))")
1760 plural_template = "nplurals=%d; plural=%s"
1761
1762 def _makePOFileWithPlural(self, language_code):
1763 pofile = removeSecurityProxy(self.factory.makePOFile(language_code))
1764 self.factory.makePOTMsgSet(
1765 pofile.potemplate, singular=u"Foo", plural=u"Bar", sequence=1)
1766 return pofile
1767
1768 def test_header_pluralform_equal(self):
1769 # If the number of plural forms in the header is equal to that in the
1770 # language entry, use the data from the language entry.
1771 sr_pofile = self._makePOFileWithPlural('sr')
1772 sr_pofile.header = self.header % self.serbian3_plural
1773
1774 translation_file_data = getAdapter(
1775 sr_pofile, ITranslationFileData, 'all_messages')
1776 self.assertEqual(3, translation_file_data.header.number_plural_forms)
1777 # The expression from the header starts with a "(", the language entry
1778 # does not.
1779 self.assertEqual(
1780 u"n%10==1 && n%100!=11",
1781 translation_file_data.header.plural_form_expression[:20])
1782
1783 def test_header_pluralform_larger(self):
1784 # If the number of plural forms in the header is larger than in the
1785 # language entry, use the data from the header.
1786 sr_pofile = self._makePOFileWithPlural('sr')
1787 sr_pofile.header = self.header % self.serbian4_plural
1788
1789 translation_file_data = getAdapter(
1790 sr_pofile, ITranslationFileData, 'all_messages')
1791 self.assertEqual(4, translation_file_data.header.number_plural_forms)
1792 self.assertEqual(
1793 u"(n==1 ? 3 : (n%10==1",
1794 translation_file_data.header.plural_form_expression[:20])
1795
1796 def test_header_pluralform_larger_but_western(self):
1797 # If the plural form expression in the header is the standard western
1798 # expression, use the data from the language entry if present.
1799 # Use Japanese because it has only one plural form which is less
1800 # than the 2 the western style has.
1801 ja_pofile = self._makePOFileWithPlural('ja')
1802 # The expression comes in different forms.
1803 for expr in ('(n != 1)', '1 != n', 'n>1', '(1 < n)'):
1804 plural_info = self.plural_template % (2, expr)
1805 ja_pofile.header = self.header % plural_info
1806
1807 translation_file_data = getAdapter(
1808 ja_pofile, ITranslationFileData, 'all_messages')
1809 nplurals_expected = 1
1810 nplurals = translation_file_data.header.number_plural_forms
1811 self.assertEqual(
1812 nplurals_expected, nplurals,
1813 "%d != %d for '%s'" % (nplurals_expected, nplurals, expr))
1814 # The plural form expression for Japanese (or any other language
1815 # with just one form) is simply '0'.
1816 self.assertEqual(
1817 u"0", translation_file_data.header.plural_form_expression)
1818
1819 def test_header_pluralform_2_but_not_western(self):
1820 # If the plural form expression in the header reports two but is not
1821 # the standard western expression, use the data from the header.
1822 # Use Japanese because it has only one plural form which is less
1823 # than the 2 the western style has.
1824 ja_pofile = self._makePOFileWithPlural('ja')
1825 ja_pofile.header = self.header % self.other_2_plural
1826
1827 translation_file_data = getAdapter(
1828 ja_pofile, ITranslationFileData, 'all_messages')
1829 self.assertEqual(2, translation_file_data.header.number_plural_forms)
1830 self.assertEqual(
1831 u"(n > 0)", translation_file_data.header.plural_form_expression)
1832
1833 def test_header_pluralform_generic(self):
1834 # If the plural form expression in the header is a generic one (no
1835 # information), use the data from the language entry if present.
1836 ja_pofile = self._makePOFileWithPlural('ja')
1837 ja_pofile.header = self.header % self.generic_plural
1838
1839 translation_file_data = getAdapter(
1840 ja_pofile, ITranslationFileData, 'all_messages')
1841 self.assertEqual(1, translation_file_data.header.number_plural_forms)
1842 self.assertEqual(
1843 u"0", translation_file_data.header.plural_form_expression)
1844
1845
1735def test_suite():1846def test_suite():
1736 return unittest.TestLoader().loadTestsFromName(__name__)1847 return TestLoader().loadTestsFromName(__name__)