Merge lp:~henninge/launchpad/bug-128324 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-128324
Merge into: lp:launchpad
Diff against target: 588 lines
8 files modified
lib/lp/testing/factory.py (+2/-4)
lib/lp/translations/doc/potmsgset.txt (+7/-69)
lib/lp/translations/interfaces/potemplate.py (+15/-7)
lib/lp/translations/model/potemplate.py (+14/-6)
lib/lp/translations/tests/test_pofile.py (+48/-12)
lib/lp/translations/tests/test_potmsgset.py (+95/-1)
lib/lp/translations/tests/test_shared_potemplate.py (+11/-38)
lib/lp/translations/tests/test_vpoexport.py (+0/-62)
To merge this branch: bzr merge lp:~henninge/launchpad/bug-128324
Reviewer Review Type Date Requested Status
Jeroen T. Vermeulen (community) Approve
Review via email: mp+13946@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Henning Eggers (henninge) wrote :
Download full text (3.2 KiB)

= Details =
See bug 128324.
This branch only contains half the fix as proposed in the bug. It adds the creation of dummy translations to the creation of POTMsgSets. The question of where the creation of POTMsgSets actually happens lead to some more related changes so that it is best to land this part separately now.

A POTMsgSet is created by POTemplate.createPOTMsgSetFromMsgIDs() whose only call site is in POTemplate.createMessageSetFromText(). This used to create an "unbound" POTMsgSet that is not linked to a POTemplate by a TranslationTemplateItem instance. This had to be done by a subsequent call to setSequence.

Having identified createPOTMsgSetFromMsgIDs as the place where POTMsgSets are born, I thought that might be a good place to put the "create dummy translations for all pofiles that belong to this potemplate". But wait, the POTMsgSet had not yet officially been linked to the POTemplate, so setting translations in its POFile seems premature.

The first obvious solution was to do it in setSequence but that seemed to be too much because that methods gets called a lot when re-importing templates where the order has changed.

So really the question is: Should unbound POTMsgSets exist at all? My answer is a clear: No, there is no point in having them. The logical solution is to set the sequence to 0 in createPOTMsgSetFromMsgIDs which the only production call site for createMessageSetFromText had done anyway.

So it was only the makePOTMsgSet factory method that needed to be adjusted too and any test that depended on this missfeature. Luckily they were few.

== Implementation details ==
I decided to move some tests from the doctest to the unit tests for better coverage. Also, testing POTMsgSet.setTranslationCreditsToTranslated separately does not make sense anymore because the factory method will already call it. So it is now tested as part of the creation test.

One of the call sites for createMessageSetFromText was in the old test_vpoexport.py whose content I could move to test_pofile.py completely, thereby removing this relict.

== Test ==

Run the new tests and those affected by the change. I ran all of lp.translations tests to find out which were affected by the test. (A full ec2 test run has taken place since then, too.)

bin/test -vvt potmsgset.txt -t TestTranslationCredits -t getTranslationRows_sequence -t shared_potemplate

== QA/Demo ==

1. Download an existing potemplate that does not have translator-credits.
2. Add translator-credits to the template and import it again.
3. Filter for untranslated messages in any of the languages that this template has translations in.
4. The translator-credits message should not appear among the untranslated messages.

= Launchpad lint =

Checking for conflicts. and issues in doctests and templates.
Running jslint, xmllint, pyflakes, and pylint.
Using normal rules.

Linting changed files:
  lib/lp/testing/factory.py
  lib/lp/translations/doc/potmsgset.txt
  lib/lp/translations/interfaces/potemplate.py
  lib/lp/translations/model/potemplate.py
  lib/lp/translations/tests/test_pofile.py
  lib/lp/translations/tests/test_potmsgset.py
  lib/lp/translations/tests/test_shared_potemplate.py

== Pyli...

Read more...

Revision history for this message
Henning Eggers (henninge) wrote :

I missed a test...

Directly related:
bin/test -vvt potmsgset.txt -t TestPOTMsgSetTranslationCredits

Indirectly related:
bin/test -vvt TestTranslationCredits -t getTranslationRows_sequence -t shared_potemplate

Revision history for this message
Jeroen T. Vermeulen (jtv) wrote :

Looks good; I particularly like the tech debt payoff component in this branch.

It's not really explicit, but I take it the "half" of the bug that you're not solving here is the one where you mark credits as translated when you create a new POFile. If so, there really ought to be a separate bug about that. Could you see to it?

One nit: _launchpad_credits_text is a really horrible name for a function. The leading underscore isn't needed since it's not in __all__, and the name should start with a verb. Personally I'd call this compose_launchpad_credits_text.

Jeroen

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/testing/factory.py'
2--- lib/lp/testing/factory.py 2009-10-23 13:51:40 +0000
3+++ lib/lp/testing/factory.py 2009-10-26 15:28:11 +0000
4@@ -1566,14 +1566,12 @@
5 create_sharing=create_sharing)
6
7 def makePOTMsgSet(self, potemplate, singular=None, plural=None,
8- context=None, sequence=None):
9+ context=None, sequence=0):
10 """Make a new `POTMsgSet` in the given template."""
11 if singular is None and plural is None:
12 singular = self.getUniqueString()
13 potmsgset = potemplate.createMessageSetFromText(
14- singular, plural, context=context)
15- if sequence is not None:
16- potmsgset.setSequence(potemplate, sequence)
17+ singular, plural, context, sequence)
18 naked_potmsgset = removeSecurityProxy(potmsgset)
19 naked_potmsgset.sync()
20 return potmsgset
21
22=== modified file 'lib/lp/translations/doc/potmsgset.txt'
23--- lib/lp/translations/doc/potmsgset.txt 2009-10-22 15:51:58 +0000
24+++ lib/lp/translations/doc/potmsgset.txt 2009-10-26 15:28:11 +0000
25@@ -34,79 +34,17 @@
26 is_translation_credit indicates if the POTMsgSet is translation credits. The
27 property translation_credit_type contains the type of translation credits.
28
29- >>> def print_credits(credits):
30- ... print credits.is_translation_credit
31- ... print credits.translation_credits_type.title
32-
33- >>> print_credits(factory.makePOTMsgSet(potemplate))
34+ >>> print potmsgset.is_translation_credit
35 False
36+ >>> print potmsgset.translation_credits_type.title
37 Not a translation credits message
38
39- >>> print_credits(factory.makePOTMsgSet(
40- ... potemplate, singular=u'translator-credits'))
41- True
42- Gnome credits message
43-
44- >>> print_credits(factory.makePOTMsgSet(
45- ... potemplate, singular=u'translation-credits'))
46- True
47- Gnome credits message
48-
49- >>> print_credits(factory.makePOTMsgSet(
50- ... potemplate,
51- ... singular=u'Your emails', context=u'EMAIL OF TRANSLATORS'))
52- True
53- KDE emails credits message
54-
55- >>> print_credits(factory.makePOTMsgSet(
56- ... potemplate, singular=u'_: EMAIL OF TRANSLATORS\nYour emails'))
57- True
58- KDE emails credits message
59-
60-
61-== POTMsgSet.setTranslationCreditsToTranslated ==
62-
63-If a message is a translation credits message, its translations must be set
64-to some dummy value so that they are counted as "translated" and don't
65-mess up the statistics.
66-
67- >>> eo_pofile = factory.makePOFile('eo', potemplate=potemplate)
68- >>> eo_language = eo_pofile.language
69- >>> gnome_credits = factory.makePOTMsgSet(
70+ >>> credits = factory.makePOTMsgSet(
71 ... potemplate, singular=u'translator-credits')
72- >>> current = gnome_credits.getCurrentTranslationMessage(potemplate,
73- ... eo_language)
74- >>> print current
75- None
76- >>> login("foo.bar@canonical.com")
77- >>> gnome_credits.setTranslationCreditsToTranslated(eo_pofile)
78- >>> current = gnome_credits.getCurrentTranslationMessage(potemplate,
79- ... eo_language)
80- >>> print current.msgstr0.translation
81- This is a dummy translation so that the credits are counted as translated.
82-
83-An imported translation credits message will already contain a translation
84-and is therefore left untouched.
85-
86- >>> from zope.security.proxy import removeSecurityProxy
87- >>> sr_pofile = removeSecurityProxy(factory.makePOFile('sr', potemplate=potemplate))
88- >>> sr_language = sr_pofile.language
89- >>> sr_credits = factory.makeTranslationMessage(
90- ... potmsgset=gnome_credits, pofile=sr_pofile, is_imported=True,
91- ... translations=[u"Some translations credits for Serbian."])
92- >>> gnome_credits.setTranslationCreditsToTranslated(sr_pofile)
93- >>> current = gnome_credits.getCurrentTranslationMessage(potemplate,
94- ... sr_language)
95- >>> print current.msgstr0.translation
96- Some translations credits for Serbian.
97-
98-Normal messages will be left untouched, too.
99-
100- >>> potmsgset.setTranslationCreditsToTranslated(sr_language)
101- >>> current = potmsgset.getCurrentTranslationMessage(potemplate,
102- ... sr_pofile)
103- >>> print current
104- None
105+ >>> print credits.is_translation_credit
106+ True
107+ >>> print credits.translation_credits_type.title
108+ Gnome credits message
109
110
111 == POTMsgSet.normalizeWhitespaces ==
112
113=== modified file 'lib/lp/translations/interfaces/potemplate.py'
114--- lib/lp/translations/interfaces/potemplate.py 2009-10-23 21:50:23 +0000
115+++ lib/lp/translations/interfaces/potemplate.py 2009-10-26 15:28:11 +0000
116@@ -463,27 +463,35 @@
117 """
118
119 def createPOTMsgSetFromMsgIDs(msgid_singular, msgid_plural=None,
120- context=None):
121+ context=None, sequence=0):
122 """Creates a new template message in the database.
123
124 :param msgid_singular: A reference to a singular msgid.
125 :param msgid_plural: A reference to a plural msgid. Can be None
126- if the message is not a plural message.
127+ if the message is not a plural message.
128 :param context: A context for the template message differentiating
129- it from other template messages with exactly the same `msgid`.
130+ it from other template messages with exactly the same `msgid`.
131+ :param sequence: The sequence number of this POTMsgSet within this
132+ POTemplate. If 0, it is considered obsolete.
133 :return: The newly created message set.
134 """
135
136- def createMessageSetFromText(singular_text, plural_text, context=None):
137+ def createMessageSetFromText(singular_text, plural_text,
138+ context=None, sequence=0):
139 """Creates a new template message in the database using strings.
140
141 Similar to createMessageSetFromMessageID, but takes text objects
142 (unicode or string) along with textual context, rather than a
143 message IDs.
144
145- For non-plural messages, plural_text should be None.
146-
147- Returns the newly created message set.
148+ :param singular_text: The string for the singular msgid.
149+ :param msgid_plural: The string for the plural msgid. Must be None
150+ if the message is not a plural message.
151+ :param context: A context for the template message differentiating
152+ it from other template messages with exactly the same `msgid`.
153+ :param sequence: The sequence number of this POTMsgSet within this
154+ POTemplate. If 0, it is considered obsolete.
155+ :return: The newly created message set.
156 """
157
158 def getOrCreateSharedPOTMsgSet(singular_text, plural_text, context=None):
159
160=== modified file 'lib/lp/translations/model/potemplate.py'
161--- lib/lp/translations/model/potemplate.py 2009-10-23 21:50:23 +0000
162+++ lib/lp/translations/model/potemplate.py 2009-10-26 15:28:11 +0000
163@@ -799,9 +799,9 @@
164 return DummyPOFile(self, language, variant=variant, owner=requester)
165
166 def createPOTMsgSetFromMsgIDs(self, msgid_singular, msgid_plural=None,
167- context=None):
168+ context=None, sequence=0):
169 """See `IPOTemplate`."""
170- return POTMsgSet(
171+ potmsgset = POTMsgSet(
172 context=context,
173 msgid_singular=msgid_singular,
174 msgid_plural=msgid_plural,
175@@ -812,6 +812,15 @@
176 sourcecomment=None,
177 flagscomment=None)
178
179+ potmsgset.setSequence(self, sequence)
180+ if potmsgset.is_translation_credit:
181+ for language in self.languages():
182+ pofile = self.getPOFileByLang(language.code)
183+ if pofile is not None:
184+ potmsgset.setTranslationCreditsToTranslated(pofile)
185+
186+ return potmsgset
187+
188 def getOrCreatePOMsgID(self, text):
189 """Creates or returns existing POMsgID for given `text`."""
190 try:
191@@ -824,7 +833,7 @@
192 return msgid
193
194 def createMessageSetFromText(self, singular_text, plural_text,
195- context=None):
196+ context=None, sequence=0):
197 """See `IPOTemplate`."""
198
199 msgid_singular = self.getOrCreatePOMsgID(singular_text)
200@@ -837,7 +846,7 @@
201 " primary msgid and context '%r'" % context)
202
203 return self.createPOTMsgSetFromMsgIDs(msgid_singular, msgid_plural,
204- context)
205+ context, sequence)
206
207 def getOrCreateSharedPOTMsgSet(self, singular_text, plural_text,
208 context=None):
209@@ -851,8 +860,7 @@
210 context, sharing_templates=True)
211 if potmsgset is None:
212 potmsgset = self.createMessageSetFromText(
213- singular_text, plural_text, context)
214- potmsgset.setSequence(self, 0)
215+ singular_text, plural_text, context, sequence=0)
216 return potmsgset
217
218 def importFromQueue(self, entry_to_import, logger=None, txn=None):
219
220=== modified file 'lib/lp/translations/tests/test_pofile.py'
221--- lib/lp/translations/tests/test_pofile.py 2009-10-20 19:34:26 +0000
222+++ lib/lp/translations/tests/test_pofile.py 2009-10-26 15:28:11 +0000
223@@ -926,6 +926,14 @@
224 self.credits_potmsgset = self.factory.makePOTMsgSet(
225 potemplate=self.potemplate, singular=u'translator-credits')
226
227+ def compose_launchpad_credits_text(self, imported_credits_text):
228+ return u"%s\n\nLaunchpad Contributions:\n %s" % (
229+ imported_credits_text,
230+ "\n ".join(["%s %s" % (person.displayname,
231+ canonical_url(person))
232+ for person in self.pofile.contributors])
233+ )
234+
235 def test_prepareTranslationCredits_extending(self):
236 # This test ensures that continuous updates to the translation credits
237 # don't result in duplicate entries.
238@@ -933,10 +941,6 @@
239 person = self.factory.makePerson()
240
241 imported_credits_text = u"Imported Contributor <name@project.org>"
242- launchpad_credits_text = (
243- u"%s\n\nLaunchpad Contributions:\n %s %s" % (
244- imported_credits_text, person.displayname,
245- canonical_url(person)))
246
247 # Import a translation credits message to 'translator-credits'.
248 self.factory.makeTranslationMessage(
249@@ -954,7 +958,9 @@
250 # The first translation credits export.
251 credits_text = self.pofile.prepareTranslationCredits(
252 self.credits_potmsgset)
253- self.assertEquals(launchpad_credits_text, credits_text)
254+ self.assertEquals(
255+ self.compose_launchpad_credits_text(imported_credits_text),
256+ credits_text)
257
258 # Now, re-import this generated message.
259 self.factory.makeTranslationMessage(
260@@ -965,7 +971,9 @@
261
262 credits_text = self.pofile.prepareTranslationCredits(
263 self.credits_potmsgset)
264- self.assertEquals(launchpad_credits_text, credits_text)
265+ self.assertEquals(
266+ self.compose_launchpad_credits_text(imported_credits_text),
267+ credits_text)
268
269
270 class TestTranslationPOFilePOTMsgSetOrdering(TestCaseWithFactory):
271@@ -1487,21 +1495,49 @@
272
273 layer = ZopelessDatabaseLayer
274
275+ # The sequence number 0 is put at the beginning of the data to verify that
276+ # it really gets sorted to the end.
277+ TEST_MESSAGES = [
278+ {'msgid':'computer', 'string':'komputilo', 'sequence':0},
279+ {'msgid':'mouse', 'string':'muso', 'sequence':0},
280+ {'msgid':'Good morning', 'string':'Bonan matenon', 'sequence':2},
281+ {'msgid':'Thank you', 'string':'Dankon', 'sequence':1},
282+ ]
283+ EXPECTED_SEQUENCE = [1, 2, 0, 0]
284+
285 def setUp(self):
286 # Create a POFile to calculate statistics on.
287 super(TestPOFile, self).setUp()
288- self.pofile = self.factory.makePOFile('sr')
289+ self.pofile = self.factory.makePOFile('eo')
290 self.potemplate = self.pofile.potemplate
291
292- # Create a single POTMsgSet that is used across all tests.
293- self.potmsgset = self.factory.makePOTMsgSet(self.potemplate,
294- sequence=1)
295-
296 def test_makeTranslatableMessage(self):
297 # TranslatableMessages can be created from the PO file
298- message = self.pofile.makeTranslatableMessage(self.potmsgset)
299+ potmsgset = self.factory.makePOTMsgSet(self.potemplate,
300+ sequence=1)
301+ message = self.pofile.makeTranslatableMessage(potmsgset)
302 verifyObject(ITranslatableMessage, message)
303
304+ def _createMessageSet(self, testmsg):
305+ # Create a message set from the test data.
306+ pomsgset = self.factory.makePOTMsgSet(
307+ self.potemplate, testmsg['msgid'], sequence=testmsg['sequence'])
308+ pomsgset.updateTranslation(
309+ self.pofile, self.pofile.owner,
310+ {0:testmsg['string'],},
311+ True, None, force_edition_rights=True)
312+
313+ def test_getTranslationRows_sequence(self):
314+ # Test for correct sorting of obsolete messages (where sequence=0).
315+ msgsets = [
316+ self._createMessageSet(msg) for msg in self.TEST_MESSAGES]
317+ for rownum, row in enumerate(
318+ self.pofile.getTranslationRows()):
319+ self.failUnlessEqual(
320+ row.sequence, self.EXPECTED_SEQUENCE[rownum],
321+ "getTranslationRows does not sort obsolete messages "
322+ "(sequence=0) to the end of the file.")
323+
324
325 def test_suite():
326 return unittest.TestLoader().loadTestsFromName(__name__)
327
328=== modified file 'lib/lp/translations/tests/test_potmsgset.py'
329--- lib/lp/translations/tests/test_potmsgset.py 2009-08-26 16:24:02 +0000
330+++ lib/lp/translations/tests/test_potmsgset.py 2009-10-26 15:28:11 +0000
331@@ -20,7 +20,7 @@
332 from lp.registry.interfaces.person import IPersonSet
333 from lp.services.worlddata.interfaces.language import ILanguageSet
334 from lp.translations.interfaces.potmsgset import (
335- POTMsgSetInIncompatibleTemplatesError)
336+ POTMsgSetInIncompatibleTemplatesError, TranslationCreditsType)
337 from lp.translations.interfaces.translationfileformat import (
338 TranslationFileFormat)
339 from lp.translations.interfaces.translationmessage import TranslationConflict
340@@ -1078,5 +1078,99 @@
341 self.assertFalse(tm2.is_imported)
342
343
344+class TestPOTMsgSetTranslationCredits(TestCaseWithFactory):
345+ """Test methods related to TranslationCredits."""
346+
347+ layer = ZopelessDatabaseLayer
348+
349+ def setUp(self):
350+ super(TestPOTMsgSetTranslationCredits, self).setUp()
351+ self.potemplate = self.factory.makePOTemplate()
352+
353+ def test_creation_credits(self):
354+ # Upon creation of a translation credits message,
355+ # dummy translations are inserted for each POFile.
356+ eo_pofile = self.factory.makePOFile('eo', potemplate=self.potemplate)
357+ sr_pofile = self.factory.makePOFile('sr', potemplate=self.potemplate)
358+
359+ credits = self.factory.makePOTMsgSet(
360+ self.potemplate, u'translator-credits', sequence=1)
361+
362+ eo_translation = credits.getCurrentTranslationMessage(
363+ self.potemplate, eo_pofile.language)
364+ self.assertIsNot(None, eo_translation,
365+ "Translation credits are not translated upon creation.")
366+
367+ sr_translation = credits.getCurrentTranslationMessage(
368+ self.potemplate, sr_pofile.language)
369+ self.assertIsNot(None, sr_translation,
370+ "Translation credits are not translated upon "
371+ "creation in 2nd POFile.")
372+
373+ def test_creation_not_translated(self):
374+ # Normal messages do not receive a dummy translation.
375+ eo_pofile = self.factory.makePOFile('eo', potemplate=self.potemplate)
376+
377+ potmsgset = self.factory.makePOTMsgSet(self.potemplate, sequence=1)
378+ eo_translation = potmsgset.getCurrentTranslationMessage(
379+ self.potemplate, eo_pofile.language)
380+ self.assertIs(None, eo_translation)
381+
382+ def test_creation_not_imported(self):
383+ # Dummy translation for translation credits are not created as
384+ # imported and can therefore be overwritten by later imports.
385+ eo_pofile = self.factory.makePOFile('eo', potemplate=self.potemplate)
386+ imported_credits = u'Imported credits.'
387+
388+ credits = self.factory.makePOTMsgSet(
389+ self.potemplate, u'translator-credits', sequence=1)
390+ translation = self.factory.makeTranslationMessage(eo_pofile, credits,
391+ translations=[imported_credits], is_imported=True)
392+
393+ eo_translation = credits.getCurrentTranslationMessage(
394+ self.potemplate, eo_pofile.language)
395+ self.assertEqual(imported_credits, eo_translation.msgstr0.translation,
396+ "Imported translation credits do not replace dummy credits.")
397+
398+ def test_translation_credits_gnome(self):
399+ # Detect all known variations of Gnome translator credits.
400+ gnome_credits = [
401+ u'translator-credits',
402+ u'translator_credits',
403+ u'translation-credits',
404+ ]
405+ for sequence, credits_string in enumerate(gnome_credits):
406+ credits = self.factory.makePOTMsgSet(
407+ self.potemplate, credits_string, sequence=sequence+1)
408+ self.assertTrue(credits.is_translation_credit)
409+ self.assertEqual(TranslationCreditsType.GNOME,
410+ credits.translation_credits_type)
411+
412+ def test_translation_credits_kde(self):
413+ # Detect all known variations of KDE translator credits.
414+ kde_credits = [
415+ (u'Your emails', u'EMAIL OF TRANSLATORS',
416+ TranslationCreditsType.KDE_EMAILS),
417+ (u'Your names', u'NAME OF TRANSLATORS',
418+ TranslationCreditsType.KDE_NAMES),
419+ ]
420+ sequence = 0
421+ for credits_string, context, credits_type in kde_credits:
422+ sequence += 1
423+ credits = self.factory.makePOTMsgSet(
424+ self.potemplate, credits_string,
425+ context=context, sequence=sequence)
426+ self.assertTrue(credits.is_translation_credit)
427+ self.assertEqual(credits_type, credits.translation_credits_type)
428+
429+ # Old KDE style.
430+ sequence += 1
431+ credits = self.factory.makePOTMsgSet(
432+ self.potemplate, u'_: %s\n%s' % (context, credits_string),
433+ sequence=sequence)
434+ self.assertTrue(credits.is_translation_credit)
435+ self.assertEqual(credits_type, credits.translation_credits_type)
436+
437+
438 def test_suite():
439 return unittest.TestLoader().loadTestsFromName(__name__)
440
441=== modified file 'lib/lp/translations/tests/test_shared_potemplate.py'
442--- lib/lp/translations/tests/test_shared_potemplate.py 2009-07-17 00:26:05 +0000
443+++ lib/lp/translations/tests/test_shared_potemplate.py 2009-10-26 15:28:11 +0000
444@@ -53,32 +53,20 @@
445
446 def test_getPOTMsgSetByMsgIDText(self):
447 potmsgset = self.factory.makePOTMsgSet(self.devel_potemplate,
448- singular="Open file")
449-
450- # It's still not present in the PO template.
451- read_potmsgset = self.devel_potemplate.getPOTMsgSetByMsgIDText(
452- "Open file")
453- self.assertEquals(read_potmsgset, None)
454-
455- # To actually insert it into a POTemplate, it needs
456- # a sequence to be set.
457- potmsgset.setSequence(self.devel_potemplate, 2)
458+ singular="Open file",
459+ sequence=2)
460+
461+ # We can retrieve the potmsgset by its ID text.
462 read_potmsgset = self.devel_potemplate.getPOTMsgSetByMsgIDText(
463 "Open file")
464 self.assertEquals(potmsgset, read_potmsgset)
465
466 def test_getPOTMsgSetBySequence(self):
467- potmsgset = self.factory.makePOTMsgSet(self.devel_potemplate)
468 sequence = self.factory.getUniqueInteger()
469-
470- # It's still not present in the PO template.
471- read_potmsgset = self.devel_potemplate.getPOTMsgSetBySequence(
472- sequence)
473- self.assertEquals(read_potmsgset, None)
474-
475- # Now we set the appropriate sequence in a potemplate and see that
476- # it works.
477- potmsgset.setSequence(self.devel_potemplate, sequence)
478+ potmsgset = self.factory.makePOTMsgSet(self.devel_potemplate,
479+ sequence=sequence)
480+
481+ # We can retrieve the potmsgset by its sequence.
482 read_potmsgset = self.devel_potemplate.getPOTMsgSetBySequence(
483 sequence)
484 self.assertEquals(potmsgset, read_potmsgset)
485@@ -89,16 +77,11 @@
486 self.assertEquals(read_potmsgset, None)
487
488 def test_getPOTMsgSetByID(self):
489- potmsgset = self.factory.makePOTMsgSet(self.devel_potemplate)
490+ potmsgset = self.factory.makePOTMsgSet(self.devel_potemplate,
491+ sequence=3)
492 id = potmsgset.id
493
494- # It's still not present in the PO template.
495- read_potmsgset = self.devel_potemplate.getPOTMsgSetByID(id)
496- self.assertEquals(read_potmsgset, None)
497-
498- # Now we set the appropriate sequence in a potemplate and see that
499- # we can get it by ID.
500- potmsgset.setSequence(self.devel_potemplate, 3)
501+ # We can retrieve the potmsgset by its ID.
502 read_potmsgset = self.devel_potemplate.getPOTMsgSetByID(id)
503 self.assertEquals(potmsgset, read_potmsgset)
504
505@@ -122,16 +105,6 @@
506 present_msgid_singular, present_msgid_plural, present_context)
507 self.assertEquals(has_message_id, True)
508
509- # A new POTMsgSet that is not part of the POTemplate cannot
510- # be gotten using hasMessageID on a POTemplate.
511- absent_potmsgset = self.factory.makePOTMsgSet(self.devel_potemplate)
512- absent_msgid_singular = absent_potmsgset.msgid_singular
513- absent_msgid_plural = absent_potmsgset.msgid_plural
514- absent_context = absent_potmsgset.msgid_plural
515- has_message_id = naked_potemplate.hasMessageID(
516- absent_msgid_singular, absent_msgid_plural, absent_context)
517- self.assertEquals(has_message_id, False)
518-
519 def test_hasPluralMessage(self):
520 naked_potemplate = removeSecurityProxy(self.devel_potemplate)
521
522
523=== removed file 'lib/lp/translations/tests/test_vpoexport.py'
524--- lib/lp/translations/tests/test_vpoexport.py 2009-07-22 11:52:40 +0000
525+++ lib/lp/translations/tests/test_vpoexport.py 1970-01-01 00:00:00 +0000
526@@ -1,62 +0,0 @@
527-# Copyright 2009 Canonical Ltd. This software is licensed under the
528-# GNU Affero General Public License version 3 (see the file LICENSE).
529-
530-"""PO file export view tests."""
531-
532-__metaclass__ = type
533-
534-import unittest
535-import transaction
536-
537-from lp.testing.factory import LaunchpadObjectFactory
538-from canonical.testing import LaunchpadZopelessLayer
539-
540-# The sequence number 0 is put at the beginning of the data to verify that
541-# it really gets sorted to the end.
542-TEST_MESSAGES = [
543- {'msgid':'computer', 'string':'komputilo', 'sequence':0},
544- {'msgid':'mouse', 'string':'muso', 'sequence':0},
545- {'msgid':'Good morning', 'string':'Bonan matenon', 'sequence':2},
546- {'msgid':'Thank you', 'string':'Dankon', 'sequence':1},
547- ]
548-EXPECTED_SEQUENCE = [1, 2, 0, 0]
549-
550-class VPOExportSetTestCase(unittest.TestCase):
551- """Test the PO file export view."""
552- layer = LaunchpadZopelessLayer
553-
554- def _createMessageSet(self, testmsg):
555- # Create a message set from the test data.
556- msgset = self.potemplate.createMessageSetFromText(
557- testmsg['msgid'], None)
558- msgset.setSequence(self.potemplate, testmsg['sequence'])
559- msgset.updateTranslation(
560- self.pofile, self.submitter_person,
561- {0:testmsg['string'],},
562- True, None, force_edition_rights=True)
563-
564- def setUp(self):
565- factory = LaunchpadObjectFactory()
566-
567- # Create a PO file and fill with test data.
568- self.potemplate = factory.makePOTemplate()
569- self.pofile = factory.makePOFile('eo', self.potemplate)
570- self.submitter_person = factory.makePerson()
571- self.msgsets = [
572- self._createMessageSet(msg) for msg in TEST_MESSAGES]
573-
574- transaction.commit()
575-
576- def test_getTranslationRows_sequence(self):
577- # Test for correct sorting of obsolete messages (where sequence=0).
578- for rownum, row in enumerate(
579- self.pofile.getTranslationRows()):
580- self.failUnlessEqual(
581- row.sequence, EXPECTED_SEQUENCE[rownum],
582- "VPOExportSet does not sort obsolete messages (sequence=0) "
583- "to the end of the file.")
584-
585-def test_suite():
586- suite = unittest.TestSuite()
587- suite.addTest(unittest.makeSuite(VPOExportSetTestCase))
588- return suite