Merge lp:~jtv/launchpad/recife-traits into lp:~launchpad/launchpad/recife

Proposed by Jeroen T. Vermeulen
Status: Merged
Approved by: Jeroen T. Vermeulen
Approved revision: no longer in the source branch.
Merged at revision: 9149
Proposed branch: lp:~jtv/launchpad/recife-traits
Merge into: lp:~launchpad/launchpad/recife
Diff against target: 1222 lines (+519/-195)
10 files modified
lib/lp/translations/configure.zcml (+13/-0)
lib/lp/translations/interfaces/side.py (+71/-0)
lib/lp/translations/interfaces/translationmessage.py (+10/-4)
lib/lp/translations/interfaces/translations.py (+0/-10)
lib/lp/translations/model/potmsgset.py (+68/-101)
lib/lp/translations/model/side.py (+79/-0)
lib/lp/translations/model/translationmessage.py (+6/-7)
lib/lp/translations/tests/test_potmsgset.py (+83/-70)
lib/lp/translations/tests/test_setcurrenttranslation.py (+3/-3)
lib/lp/translations/tests/test_side.py (+186/-0)
To merge this branch: bzr merge lp:~jtv/launchpad/recife-traits
Reviewer Review Type Date Requested Status
Henning Eggers (community) code Approve
Review via email: mp+31729@code.launchpad.net

Commit message

Translation side traits.

Description of the change

= Translation side traits =

For merging into our "recife" feature branch, which changes how we model how Ubuntu and non-Ubuntu translations interact and which translation messages are the "current" ones.

This is a pattern that came in handy while implementing POTMsgSet.setCurrentTranslation: some external "traits" classes that summarize the parameters of the side of translation that you're currently working on—upstream or Ubuntu. In the "Recife" model that Translations is migrating to, the two use separate flags to indicate which TranslationMessages they consider current.

A lot of the changes appear unrelated: since the traits are provided by a utility, I had to involve Zope in some existing tests that then stumbled over security proxies. That meant more logins and one or two interface extensions.

There's a few tiny bits of lint left where I'm not sure the linter is right: a comment that counts as a blank line and two cases where the formatting for list comprehensions that we were once told to employ is considered whitespace-before-]. The other stuff I cleaned up.

To test:
{{{
./bin/test -vvc -m lp.translations.tests -t potmsgset -t setcurrent
}}}

Jeroen

To post a comment you must log in.
Revision history for this message
Henning Eggers (henninge) wrote :

Thanks for the traits! ;-)
I think they are a good idea but we will have to watch to keep them simple. We talked about the helper class that is left in here for historical reason and I would be glad to see it removed in another branch soon.
Other than that I didn't find any problems. ;-)

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/translations/configure.zcml'
2--- lib/lp/translations/configure.zcml 2010-07-23 09:41:07 +0000
3+++ lib/lp/translations/configure.zcml 2010-08-06 07:43:48 +0000
4@@ -570,6 +570,19 @@
5 <allow
6 interface="lp.translations.interfaces.translationmessage.ITranslationMessageSet"/>
7 </securedutility>
8+
9+ <!-- TranslationSideTraits -->
10+ <class class="lp.translations.model.side.TranslationSideTraits">
11+ <allow interface="lp.translations.interfaces.side.ITranslationSideTraits"/>
12+ </class>
13+
14+ <!-- TranslationSideTraitsSet -->
15+ <securedutility
16+ class="lp.translations.model.side.TranslationSideTraitsSet"
17+ provides="lp.translations.interfaces.side.ITranslationSideTraitsSet">
18+ <allow
19+ interface="lp.translations.interfaces.side.ITranslationSideTraitsSet"/>
20+ </securedutility>
21 </facet>
22 <adapter
23 provides="canonical.launchpad.webapp.interfaces.IBreadcrumb"
24
25=== added file 'lib/lp/translations/interfaces/side.py'
26--- lib/lp/translations/interfaces/side.py 1970-01-01 00:00:00 +0000
27+++ lib/lp/translations/interfaces/side.py 2010-08-06 07:43:48 +0000
28@@ -0,0 +1,71 @@
29+# Copyright 2010 Canonical Ltd. This software is licensed under the
30+# GNU Affero General Public License version 3 (see the file LICENSE).
31+
32+"""Traits of the two "sides" of translation: Ubuntu and upstream."""
33+
34+__metaclass__ = type
35+__all__ = [
36+ 'ITranslationSideTraits',
37+ 'ITranslationSideTraitsSet',
38+ 'TranslationSide',
39+ ]
40+
41+from zope.interface import Attribute, Interface
42+from zope.schema import TextLine
43+
44+from lazr.restful.fields import Reference
45+
46+
47+class TranslationSide:
48+ """The two "sides" of software that can be translated in Launchpad.
49+
50+ These are "upstream" and "Ubuntu."
51+ """
52+ UPSTREAM = 1
53+ UBUNTU = 2
54+
55+
56+class ITranslationSideTraits(Interface):
57+ """Traits describing a "side": upstream or Ubuntu.
58+
59+ Encapsulates primitives that depend on translation side: finding the
60+ message that is current on the given side, checking the flag that
61+ says whether a message is current on this side, setting or clearing
62+ the flag, and providing the same capabilities for the other side.
63+
64+ For an introduction to the Traits pattern, see
65+ http://www.cantrip.org/traits.html
66+ """
67+ side = Attribute("This TranslationSide")
68+ other_side_traits = Reference(
69+ Interface, title=u"Traits for other side.", required=True,
70+ readonly=True)
71+ flag_name = TextLine(
72+ title=u"The TranslationMessage flag for this side",
73+ required=True, readonly=True)
74+
75+ def getCurrentMessage(potemplate, potmsgset, language):
76+ """Find the current message on this side, if any."""
77+
78+ def getFlag(translationmessage):
79+ """Retrieve a message's "current" flag for this side."""
80+
81+ def setFlag(translationmessage, value):
82+ """Set a message's "current" flag for this side.
83+
84+ This is a dumb operation. It does not worry about conflicting
85+ other messages.
86+ """
87+
88+
89+class ITranslationSideTraitsSet(Interface):
90+ """Utility for `TranslationSideTraits`."""
91+
92+ def getTraits(side):
93+ """Retrieve the `TranslationSideTraits` for `side`."""
94+
95+ def getForTemplate(potemplate):
96+ """Get the `TranslationSideTraits` for `potemplate`s side."""
97+
98+ def getAllTraits():
99+ """Return dict mapping `TranslationSide` to traits objects."""
100
101=== modified file 'lib/lp/translations/interfaces/translationmessage.py'
102--- lib/lp/translations/interfaces/translationmessage.py 2010-06-18 10:50:07 +0000
103+++ lib/lp/translations/interfaces/translationmessage.py 2010-08-06 07:43:48 +0000
104@@ -125,9 +125,8 @@
105 readonly=False, required=False)
106
107 reviewer = Object(
108- title=_(
109- "The person who did the review and accepted current translations"
110- ), readonly=False, required=False, schema=IPerson)
111+ title=_("The person who reviewed and accepted this translation"),
112+ readonly=False, required=False, schema=IPerson)
113
114 # Message references for up to TranslationConstants.MAX_PLURAL_FORMS
115 # plural forms.
116@@ -218,6 +217,14 @@
117 def getOnePOFile():
118 """Get any POFile containing this translation."""
119
120+ def shareIfPossible():
121+ """Make this message shared, if possible.
122+
123+ If there is already a similar message that is shared, this
124+ message's information is merged into that of the existing one,
125+ and self is deleted.
126+ """
127+
128 def isHidden(pofile):
129 """Whether this is an unused, hidden suggestion in `pofile`.
130
131@@ -258,7 +265,6 @@
132 """
133
134
135-
136 class ITranslationMessageSuggestions(Interface):
137 """Suggested `ITranslationMessage`s for a `POTMsgSet`.
138
139
140=== modified file 'lib/lp/translations/interfaces/translations.py'
141--- lib/lp/translations/interfaces/translations.py 2010-08-04 11:00:51 +0000
142+++ lib/lp/translations/interfaces/translations.py 2010-08-06 07:43:48 +0000
143@@ -10,7 +10,6 @@
144 __all__ = [
145 'TranslationConstants',
146 'TranslationsBranchImportMode',
147- 'TranslationSide',
148 ]
149
150
151@@ -52,12 +51,3 @@
152 Import all translation files (templates and translations)
153 found in the branch.
154 """)
155-
156-
157-class TranslationSide:
158- """The two "sides" of software that can be translated in Launchpad.
159-
160- These are "upstream" and "Ubuntu."
161- """
162- UPSTREAM = 1
163- UBUNTU = 2
164
165=== modified file 'lib/lp/translations/model/potmsgset.py'
166--- lib/lp/translations/model/potmsgset.py 2010-08-04 11:00:51 +0000
167+++ lib/lp/translations/model/potmsgset.py 2010-08-06 07:43:48 +0000
168@@ -5,7 +5,7 @@
169
170 __metaclass__ = type
171 __all__ = [
172- 'make_translation_side_message_traits',
173+ 'make_message_side_helpers',
174 'POTMsgSet',
175 ]
176
177@@ -38,6 +38,8 @@
178 IPOTMsgSet,
179 POTMsgSetInIncompatibleTemplatesError,
180 TranslationCreditsType)
181+from lp.translations.interfaces.side import (
182+ ITranslationSideTraitsSet, TranslationSide)
183 from lp.translations.interfaces.translationfileformat import (
184 TranslationFileFormat)
185 from lp.translations.interfaces.translationimporter import (
186@@ -46,8 +48,7 @@
187 RosettaTranslationOrigin,
188 TranslationConflict,
189 TranslationValidationStatus)
190-from lp.translations.interfaces.translations import (
191- TranslationConstants, TranslationSide)
192+from lp.translations.interfaces.translations import TranslationConstants
193 from lp.translations.model.pomsgid import POMsgID
194 from lp.translations.model.potranslation import POTranslation
195 from lp.translations.model.translationmessage import (
196@@ -85,99 +86,68 @@
197 u'credits are counted as translated.')
198
199
200-class TranslationSideMessageTraits:
201- """Dealing with a `POTMsgSet` on either `TranslationSide`.
202-
203- Encapsulates primitives that depend on translation side: finding the
204- message that is current on the given side, checking the flag that
205- says whether a message is current on this side, setting or clearing
206- the flag, and providing the same capabilities for the other side.
207-
208- For an introduction to the Traits pattern, see
209- http://www.cantrip.org/traits.html
210+# Marker for "no incumbent message found yet."
211+incumbent_unknown = object()
212+
213+
214+class MessageSideHelper:
215+ """Helper for manipulating messages on one `TranslationSide`.
216+
217+ Does some caching so that the caller doesn't need to worry about
218+ unnecessary queries e.g. when disabling a previously current
219+ message.
220 """
221- # The TranslationSide that these Traits are for.
222- side = None
223-
224- # TranslationSideMessageTraits for this message on the "other side."
225+
226+ # The TranslationSideTraits that this helper is for.
227+ traits = None
228+
229+ # MessageSideHelper for this message on the "other side."
230 other_side = None
231
232- # Name of this side's flag.
233- flag_name = None
234+ _incumbent = incumbent_unknown
235
236- def __init__(self, potmsgset, potemplate=None, language=None,
237- variant=None):
238+ def __init__(self, side, potmsgset, potemplate=None, language=None):
239+ self.traits = getUtility(ITranslationSideTraitsSet).getTraits(side)
240 self.potmsgset = potmsgset
241 self.potemplate = potemplate
242 self.language = language
243- self.variant = variant
244-
245- self._found_incumbent = False
246
247 @property
248 def incumbent_message(self):
249 """Message that currently has the flag."""
250- if not self._found_incumbent:
251- self._incumbent = self._getIncumbentMessage()
252- self._found_incumbent = True
253+ if self._incumbent == incumbent_unknown:
254+ self._incumbent = self.traits.getCurrentMessage(
255+ self.potmsgset, self.potemplate, self.language)
256 return self._incumbent
257
258- def getFlag(self, translationmessage):
259- """Is this message the current one on this side?"""
260- return getattr(translationmessage, self.flag_name)
261-
262 def setFlag(self, translationmessage, value):
263 """Set or clear a message's "current" flag for this side."""
264- if value == self.getFlag(translationmessage):
265+ if value == self.traits.getFlag(translationmessage):
266 return
267
268- if value and self.incumbent_message is not None:
269- Store.of(self.incumbent_message).add_flush_order(
270- self.incumbent_message, translationmessage)
271- self.setFlag(self.incumbent_message, False)
272-
273- setattr(translationmessage, self.flag_name, value)
274- self._found_incumbent = False
275-
276- def _getIncumbentMessage(self):
277- """Get the message that is current on this side, if any."""
278- raise NotImplementedError('_getIncumbentMessage')
279-
280-
281-class UpstreamSideTraits(TranslationSideMessageTraits):
282- """Traits for upstream translations."""
283-
284- side = TranslationSide.UPSTREAM
285-
286- flag_name = 'is_current_upstream'
287-
288- def _getIncumbentMessage(self):
289- """See `TranslationSideMessageTraits`."""
290- return self.potmsgset.getImportedTranslationMessage(
291- self.potemplate, self.language, variant=self.variant)
292-
293-
294-class UbuntuSideTraits(TranslationSideMessageTraits):
295- """Traits for Ubuntu translations."""
296-
297- side = TranslationSide.UBUNTU
298-
299- flag_name = 'is_current_ubuntu'
300-
301- def _getIncumbentMessage(self):
302- """See `TranslationSideMessageTraits`."""
303- return self.potmsgset.getCurrentTranslationMessage(
304- self.potemplate, self.language, variant=self.variant)
305-
306-
307-def make_translation_side_message_traits(side, potmsgset, potemplate,
308- language, variant=None):
309- """Create `TranslationSideTraits` object of the appropriate subtype."""
310- ubuntu = UbuntuSideTraits(potmsgset, potemplate, language, variant)
311- upstream = UpstreamSideTraits(potmsgset, potemplate, language, variant)
312+ if value:
313+ if self.incumbent_message is not None:
314+ Store.of(self.incumbent_message).add_flush_order(
315+ self.incumbent_message, translationmessage)
316+ self.setFlag(self.incumbent_message, False)
317+ self._incumbent = translationmessage
318+ else:
319+ self._incumbent = incumbent_unknown
320+
321+ self.traits.setFlag(translationmessage, value)
322+
323+
324+def make_message_side_helpers(side, potmsgset, potemplate, language):
325+ """Create `MessageSideHelper` object of the appropriate subtype."""
326+ upstream = MessageSideHelper(
327+ TranslationSide.UPSTREAM, potmsgset, potemplate, language)
328+ ubuntu = MessageSideHelper(
329+ TranslationSide.UBUNTU, potmsgset, potemplate, language)
330 upstream.other_side = ubuntu
331 ubuntu.other_side = upstream
332- mapping = dict((traits.side, traits) for traits in (ubuntu, upstream))
333+ mapping = dict(
334+ (helper.traits.side, helper)
335+ for helper in (ubuntu, upstream))
336 return mapping[side]
337
338
339@@ -469,8 +439,9 @@
340 WHERE
341 POTMsgSet.id <> %s AND
342 msgid_singular = %s AND
343- POTemplate.iscurrent AND
344- (Product.official_rosetta OR Distribution.official_rosetta)
345+ POTemplate.iscurrent AND (
346+ Product.official_rosetta OR
347+ Distribution.official_rosetta)
348 )''' % sqlvalues(self, self.msgid_singular))
349
350 # Subquery to find the ids of TranslationMessages that are
351@@ -485,7 +456,7 @@
352 for form in xrange(TranslationConstants.MAX_PLURAL_FORMS)])
353 ids_query_params = {
354 'msgstrs': msgstrs,
355- 'where': ' AND '.join(query)
356+ 'where': ' AND '.join(query),
357 }
358 ids_query = '''
359 SELECT DISTINCT ON (%(msgstrs)s)
360@@ -826,7 +797,6 @@
361 if is_current_upstream or new_message == upstream_message:
362 new_message.makeCurrentUpstream()
363
364-
365 def _isTranslationMessageASuggestion(self, force_suggestion,
366 pofile, submitter,
367 force_edition_rights,
368@@ -1079,7 +1049,7 @@
369 return 'none'
370 elif message.is_diverged:
371 return 'diverged'
372- elif translation_side_traits.other_side.getFlag(message):
373+ elif translation_side_traits.other_side_traits.getFlag(message):
374 return 'other_shared'
375 else:
376 return 'shared'
377@@ -1100,8 +1070,7 @@
378
379 translation_args = dict(
380 ('msgstr%d' % form, translation)
381- for form, translation in translations.iteritems()
382- )
383+ for form, translation in translations.iteritems())
384
385 return TranslationMessage(
386 potmsgset=self,
387@@ -1117,14 +1086,13 @@
388 def setCurrentTranslation(self, pofile, submitter, translations, origin,
389 translation_side, share_with_other_side=False):
390 """See `IPOTMsgSet`."""
391- traits = make_translation_side_message_traits(
392- translation_side, self, pofile.potemplate, pofile.language,
393- variant=pofile.variant)
394+ helper = make_message_side_helpers(
395+ translation_side, self, pofile.potemplate, pofile.language)
396
397 translations = self._findPOTranslations(translations)
398
399 # The current message on this translation side, if any.
400- incumbent_message = traits.incumbent_message
401+ incumbent_message = helper.incumbent_message
402
403 # An already existing message, if any, that's either shared, or
404 # diverged for the template/pofile we're working on, whose
405@@ -1174,8 +1142,8 @@
406 }
407
408 incumbent_state = "incumbent_%s" % self._nameMessageStatus(
409- incumbent_message, traits)
410- twin_state = "twin_%s" % self._nameMessageStatus(twin, traits)
411+ incumbent_message, helper.traits)
412+ twin_state = "twin_%s" % self._nameMessageStatus(twin, helper.traits)
413
414 decisions = decision_matrix[incumbent_state][twin_state]
415 assert re.match('[ABZ]?[124567]?[+*]?$', decisions), (
416@@ -1185,11 +1153,11 @@
417 if character == 'A':
418 # Deactivate & converge.
419 # There may be an identical shared message.
420- traits.setFlag(incumbent_message, False)
421+ helper.traits.setFlag(incumbent_message, False)
422 incumbent_message.shareIfPossible()
423 elif character == 'B':
424 # Deactivate.
425- traits.setFlag(incumbent_message, False)
426+ helper.setFlag(incumbent_message, False)
427 elif character == 'Z':
428 # There is no incumbent message, so do nothing to it.
429 assert incumbent_message is None, (
430@@ -1210,14 +1178,14 @@
431 # (If not, it's already active and has been unmasked by
432 # our deactivating the incumbent).
433 message = twin
434- if not traits.getFlag(twin):
435- assert not traits.other_side.getFlag(twin), (
436+ if not helper.traits.getFlag(twin):
437+ assert not helper.other_side.traits.getFlag(twin), (
438 "Trying to diverge a message that is current on the "
439 "other side.")
440 message.potemplate = pofile.potemplate
441 elif character == '6':
442 # If other is not active, fork a diverged message.
443- if traits.getFlag(twin):
444+ if helper.traits.getFlag(twin):
445 message = twin
446 else:
447 # The twin is used on the other side, so we can't
448@@ -1232,11 +1200,11 @@
449 message.shareIfPossible()
450 elif character == '*':
451 if share_with_other_side:
452- if traits.other_side.incumbent_message is None:
453- traits.other_side.setFlag(message, True)
454+ if helper.other_side.incumbent_message is None:
455+ helper.other_side.setFlag(message, True)
456 elif character == '+':
457 if share_with_other_side:
458- traits.other_side.setFlag(message, True)
459+ helper.other_side.setFlag(message, True)
460 else:
461 raise AssertionError(
462 "Bad character in decision string: %s" % character)
463@@ -1244,7 +1212,7 @@
464 if decisions == '':
465 message = twin
466
467- traits.setFlag(message, True)
468+ helper.setFlag(message, True)
469
470 return message
471
472@@ -1263,7 +1231,7 @@
473 current.is_current_ubuntu = False
474 # Converge the current translation only if it is diverged and not
475 # current upstream.
476- is_diverged = current.potemplate is not None
477+ is_diverged = current.potemplate is not None
478 if is_diverged and not current.is_current_upstream:
479 current.potemplate = None
480 pofile.date_changed = UTC_NOW
481@@ -1494,4 +1462,3 @@
482 """See `IPOTMsgSet`."""
483 return TranslationTemplateItem.selectBy(
484 potmsgset=self, orderBy=['id'])
485-
486
487=== added file 'lib/lp/translations/model/side.py'
488--- lib/lp/translations/model/side.py 1970-01-01 00:00:00 +0000
489+++ lib/lp/translations/model/side.py 2010-08-06 07:43:48 +0000
490@@ -0,0 +1,79 @@
491+# Copyright 2010 Canonical Ltd. This software is licensed under the
492+# GNU Affero General Public License version 3 (see the file LICENSE).
493+
494+"""`TranslationSideTraits` implementations."""
495+
496+__metaclass__ = type
497+__all__ = [
498+ 'TranslationSideTraits',
499+ 'TranslationSideTraitsSet',
500+ ]
501+
502+from zope.interface import implements
503+
504+from lp.translations.interfaces.side import (
505+ ITranslationSideTraits,
506+ ITranslationSideTraitsSet,
507+ TranslationSide)
508+
509+
510+class TranslationSideTraits:
511+ """See `ITranslationSideTraits`."""
512+ implements(ITranslationSideTraits)
513+
514+ def __init__(self, side, flag_name):
515+ self.side = side
516+ self.other_side_traits = None
517+ self.flag_name = flag_name
518+
519+ def getFlag(self, translationmessage):
520+ """See `ITranslationSideTraits`."""
521+ return getattr(translationmessage, self.flag_name)
522+
523+ def getCurrentMessage(self, potmsgset, potemplate, language):
524+ """See `ITranslationSideTraits`."""
525+ if self.side == TranslationSide.UPSTREAM:
526+ return potmsgset.getImportedTranslationMessage(
527+ potemplate, language)
528+ else:
529+ return potmsgset.getCurrentTranslationMessage(
530+ potemplate, language)
531+
532+ def setFlag(self, translationmessage, value):
533+ """See `ITranslationSideTraits`."""
534+ if self.side == TranslationSide.UPSTREAM:
535+ translationmessage.makeCurrentUpstream(value)
536+ else:
537+ translationmessage.makeCurrentUbuntu(value)
538+
539+
540+class TranslationSideTraitsSet:
541+ """See `ITranslationSideTraitsSet`."""
542+ implements(ITranslationSideTraitsSet)
543+
544+ def __init__(self):
545+ upstream = TranslationSideTraits(
546+ TranslationSide.UPSTREAM, 'is_current_upstream')
547+ ubuntu = TranslationSideTraits(
548+ TranslationSide.UBUNTU, 'is_current_ubuntu')
549+ ubuntu.other_side_traits = upstream
550+ upstream.other_side_traits = ubuntu
551+ self.traits = dict(
552+ (traits.side, traits)
553+ for traits in [ubuntu, upstream])
554+
555+ def getTraits(self, side):
556+ """See `ITranslationSideTraitsSet`."""
557+ return self.traits[side]
558+
559+ def getForTemplate(self, potemplate):
560+ """See `ITranslationSideTraitsSet`."""
561+ if potemplate.productseries is not None:
562+ side = TranslationSide.UPSTREAM
563+ else:
564+ side = TranslationSide.UBUNTU
565+ return self.getTraits(side)
566+
567+ def getAllTraits(self):
568+ """See `ITranslationSideTraitsSet`."""
569+ return self.traits
570
571=== modified file 'lib/lp/translations/model/translationmessage.py'
572--- lib/lp/translations/model/translationmessage.py 2010-08-04 11:00:51 +0000
573+++ lib/lp/translations/model/translationmessage.py 2010-08-06 07:43:48 +0000
574@@ -161,11 +161,16 @@
575 return
576
577 def makeCurrentUbuntu(self, new_value=True):
578+ """See `ITranslationMessage`."""
579 self.is_current_ubuntu = new_value
580
581 def makeCurrentUpstream(self, new_value=True):
582+ """See `ITranslationMessage`."""
583 self.is_current_upstream = new_value
584
585+ def shareIfPossible(self):
586+ """See `ITranslationMessage`."""
587+
588
589 class TranslationMessage(SQLBase, TranslationMessageMixIn):
590 implements(ITranslationMessage)
591@@ -350,12 +355,7 @@
592 return Store.of(self).find(TranslationMessage, where_clause).one()
593
594 def shareIfPossible(self):
595- """Make this message shared, if possible.
596-
597- If there is already a similar message that is shared, this
598- message's information is merged into that of the existing one,
599- and self is deleted.
600- """
601+ """See `ITranslationMessage`."""
602 if self.potemplate is None:
603 # Already converged.
604 return
605@@ -458,7 +458,6 @@
606 self.is_current_upstream = new_value
607
608
609-
610 class TranslationMessageSet:
611 """See `ITranslationMessageSet`."""
612 implements(ITranslationMessageSet)
613
614=== modified file 'lib/lp/translations/tests/test_potmsgset.py'
615--- lib/lp/translations/tests/test_potmsgset.py 2010-07-27 11:31:46 +0000
616+++ lib/lp/translations/tests/test_potmsgset.py 2010-08-06 07:43:48 +0000
617@@ -24,32 +24,32 @@
618 TranslationFileFormat)
619 from lp.translations.interfaces.translationmessage import (
620 RosettaTranslationOrigin, TranslationConflict)
621-from lp.translations.interfaces.translations import TranslationSide
622-from lp.translations.model.potmsgset import (
623- make_translation_side_message_traits)
624+from lp.translations.interfaces.side import TranslationSide
625+from lp.translations.model.potmsgset import make_message_side_helpers
626 from lp.translations.model.translationmessage import (
627 DummyTranslationMessage)
628
629 from lp.testing import TestCaseWithFactory
630-from canonical.testing import ZopelessDatabaseLayer
631+from canonical.testing import DatabaseFunctionalLayer, ZopelessDatabaseLayer
632
633
634 class TestTranslationSharedPOTMsgSets(TestCaseWithFactory):
635 """Test discovery of translation suggestions."""
636
637- layer = ZopelessDatabaseLayer
638+ layer = DatabaseFunctionalLayer
639
640 def setUp(self):
641 """Set up context to test in."""
642 # Create a product with two series and a shared POTemplate
643 # in different series ('devel' and 'stable').
644- super(TestTranslationSharedPOTMsgSets, self).setUp()
645+ super(TestTranslationSharedPOTMsgSets, self).setUp(
646+ 'carlos@canonical.com')
647 self.foo = self.factory.makeProduct()
648 self.foo_devel = self.factory.makeProductSeries(
649 name='devel', product=self.foo)
650 self.foo_stable = self.factory.makeProductSeries(
651 name='stable', product=self.foo)
652- self.foo.official_rosetta = True
653+ removeSecurityProxy(self.foo).official_rosetta = True
654
655 # POTemplate is 'shared' if it has the same name ('messages').
656 self.devel_potemplate = self.factory.makePOTemplate(
657@@ -154,8 +154,7 @@
658 # is not used as a singular_text.
659 translation = self.factory.makeTranslationMessage(
660 pofile=en_pofile, potmsgset=potmsgset,
661- translations=[DIVERGED_ENGLISH_STRING])
662- translation.potemplate = self.devel_potemplate
663+ translations=[DIVERGED_ENGLISH_STRING], force_diverged=True)
664 self.assertEquals(potmsgset.singular_text, ENGLISH_STRING)
665
666 def test_getCurrentDummyTranslationMessage(self):
667@@ -324,7 +323,8 @@
668 # Create an external POTemplate with a POTMsgSet using
669 # the same English string as the one in self.potmsgset.
670 external_template = self.factory.makePOTemplate()
671- external_template.productseries.product.official_rosetta = True
672+ product = external_template.productseries.product
673+ removeSecurityProxy(product).official_rosetta = True
674 external_potmsgset = self.factory.makePOTMsgSet(
675 external_template,
676 singular=self.potmsgset.singular_text)
677@@ -357,7 +357,7 @@
678 imported_translation = self.factory.makeSharedTranslationMessage(
679 pofile=external_pofile, potmsgset=external_potmsgset,
680 suggestion=False, is_current_upstream=True)
681- imported_translation.is_current_ubuntu = False
682+ imported_translation.makeCurrentUbuntu(False)
683
684 transaction.commit()
685
686@@ -383,7 +383,8 @@
687 # Create an external POTemplate with a POTMsgSet using
688 # the same English string as the one in self.potmsgset.
689 external_template = self.factory.makePOTemplate()
690- external_template.productseries.product.official_rosetta = True
691+ product = external_template.productseries.product
692+ removeSecurityProxy(product).official_rosetta = True
693 external_potmsgset = self.factory.makePOTMsgSet(
694 external_template,
695 singular=self.potmsgset.singular_text)
696@@ -416,7 +417,7 @@
697 imported_translation = self.factory.makeSharedTranslationMessage(
698 pofile=external_pofile, potmsgset=external_potmsgset,
699 suggestion=False, is_current_upstream=True)
700- imported_translation.is_current_ubuntu = False
701+ imported_translation.makeCurrentUbuntu(False)
702
703 transaction.commit()
704
705@@ -460,7 +461,7 @@
706
707 # If the current upstream translation is also current in Ubuntu,
708 # it's not changed in Ubuntu.
709- current_shared.is_current_ubuntu = False
710+ current_shared.makeCurrentUbuntu(False)
711 imported_shared = self.factory.makeSharedTranslationMessage(
712 pofile=sr_pofile, potmsgset=self.potmsgset,
713 is_current_upstream=True)
714@@ -471,7 +472,7 @@
715
716 # If there's a current, diverged translation, and an imported
717 # non-current one, it's changed in Ubuntu.
718- imported_shared.is_current_ubuntu = False
719+ imported_shared.makeCurrentUbuntu(False)
720 current_diverged = self.factory.makeTranslationMessage(
721 pofile=sr_pofile, potmsgset=self.potmsgset,
722 is_current_upstream=False)
723@@ -482,7 +483,7 @@
724
725 # If the upstream one is shared and used in Ubuntu, yet there is
726 # a diverged Ubuntu translation as well, it is changed in Ubuntu.
727- imported_shared.is_current_ubuntu = False
728+ imported_shared.makeCurrentUbuntu(False)
729 self.assertEquals(
730 self.potmsgset.hasTranslationChangedInLaunchpad(
731 self.devel_potemplate, serbian),
732@@ -688,8 +689,8 @@
733 potemplate, es_pofile.language)
734 # Let's make sure this message is also marked as imported
735 # and diverged.
736- es_current.is_current_upstream = True
737- es_current.potemplate = potemplate
738+ es_current.makeCurrentUpstream(True)
739+ removeSecurityProxy(es_current).potemplate = potemplate
740
741 self.assertTrue(es_current.is_current_ubuntu)
742 self.assertNotEqual(None, es_current.potemplate)
743@@ -720,13 +721,19 @@
744 class TestPOTMsgSetSuggestions(TestCaseWithFactory):
745 """Test retrieval and dismissal of translation suggestions."""
746
747- layer = ZopelessDatabaseLayer
748+ layer = DatabaseFunctionalLayer
749
750 def _setDateCreated(self, tm):
751 removeSecurityProxy(tm).date_created = self.now()
752
753 def _setDateReviewed(self, tm):
754- removeSecurityProxy(tm).date_reviewed = self.now()
755+ naked_tm = removeSecurityProxy(tm)
756+ if naked_tm.reviewer is None:
757+ naked_tm.reviewer = self.factory.makePerson()
758+ naked_tm.date_reviewed = self.now()
759+
760+ def _setDateUpdated(self, tm):
761+ removeSecurityProxy(tm).date_updated = self.now()
762
763 def gen_now(self):
764 now = datetime.now(pytz.UTC)
765@@ -737,12 +744,12 @@
766 def setUp(self):
767 # Create a product with all the boilerplate objects to be able to
768 # create TranslationMessage objects.
769- super(TestPOTMsgSetSuggestions, self).setUp()
770+ super(TestPOTMsgSetSuggestions, self).setUp('carlos@canonical.com')
771 self.now = self.gen_now().next
772 self.foo = self.factory.makeProduct()
773 self.foo_main = self.factory.makeProductSeries(
774 name='main', product=self.foo)
775- self.foo.official_rosetta = True
776+ removeSecurityProxy(self.foo).official_rosetta = True
777
778 self.potemplate = self.factory.makePOTemplate(
779 productseries=self.foo_main, name="messages")
780@@ -752,14 +759,17 @@
781 # Set up some translation messages with dummy timestamps that will be
782 # changed in the tests.
783 self.translation = self.factory.makeTranslationMessage(
784- self.pofile, self.potmsgset, translations=[u'trans1'],
785- reviewer=self.factory.makePerson(), date_updated=self.now())
786+ removeSecurityProxy(self.pofile), self.potmsgset,
787+ translations=[u'trans1'], reviewer=self.factory.makePerson(),
788+ is_current_upstream=True, date_updated=self.now())
789 self.suggestion1 = self.factory.makeTranslationMessage(
790 self.pofile, self.potmsgset, suggestion=True,
791- translations=[u'sugg1'], date_updated=self.now())
792+ translations=[u'sugg1'], reviewer=self.factory.makePerson(),
793+ date_updated=self.now())
794 self.suggestion2 = self.factory.makeTranslationMessage(
795 self.pofile, self.potmsgset, suggestion=True,
796 translations=[u'sugg2'], date_updated=self.now())
797+ self._setDateCreated(self.suggestion2)
798
799 def test_dismiss_all(self):
800 # Set order of creation and review.
801@@ -841,7 +851,8 @@
802 transaction.commit()
803 # Make the translation a suggestion, too.
804 suggestion3 = self.translation
805- suggestion3.is_current_ubuntu = False
806+ suggestion3.makeCurrentUbuntu(False)
807+ suggestion3.makeCurrentUpstream(False)
808 self._setDateCreated(suggestion3)
809 transaction.commit()
810 # All suggestions are visible.
811@@ -914,7 +925,7 @@
812 class TestPOTMsgSetResetTranslation(TestCaseWithFactory):
813 """Test resetting the current translation."""
814
815- layer = ZopelessDatabaseLayer
816+ layer = DatabaseFunctionalLayer
817
818 def gen_now(self):
819 now = datetime.now(pytz.UTC)
820@@ -925,12 +936,13 @@
821 def setUp(self):
822 # Create a product with all the boilerplate objects to be able to
823 # create TranslationMessage objects.
824- super(TestPOTMsgSetResetTranslation, self).setUp()
825+ super(TestPOTMsgSetResetTranslation, self).setUp(
826+ 'carlos@canonical.com')
827 self.now = self.gen_now().next
828 self.foo = self.factory.makeProduct()
829 self.foo_main = self.factory.makeProductSeries(
830 name='main', product=self.foo)
831- self.foo.official_rosetta = True
832+ removeSecurityProxy(self.foo).official_rosetta = True
833
834 self.potemplate = self.factory.makePOTemplate(
835 productseries=self.foo_main, name="messages")
836@@ -997,7 +1009,7 @@
837 class TestPOTMsgSetCornerCases(TestCaseWithFactory):
838 """Test corner cases and constraints."""
839
840- layer = ZopelessDatabaseLayer
841+ layer = DatabaseFunctionalLayer
842
843 def gen_now(self):
844 now = datetime.now(pytz.UTC)
845@@ -1009,7 +1021,7 @@
846 """Set up context to test in."""
847 # Create a product with two series and a shared POTemplate
848 # in different series ('devel' and 'stable').
849- super(TestPOTMsgSetCornerCases, self).setUp()
850+ super(TestPOTMsgSetCornerCases, self).setUp('carlos@canonical.com')
851
852 self.pofile = self.factory.makePOFile('sr')
853 self.potemplate = self.pofile.potemplate
854@@ -1126,12 +1138,11 @@
855 tm1 = self.potmsgset.updateTranslation(
856 self.pofile, self.uploader, [u"tm1"], lock_timestamp=self.now(),
857 is_current_upstream=True, force_shared=True)
858+ self.assertTrue(tm1.is_current_ubuntu)
859 tm2 = self.potmsgset.updateTranslation(
860 self.pofile, self.uploader, [u"tm2"], lock_timestamp=self.now(),
861 is_current_upstream=True, force_diverged=True)
862- tm2.is_current_ubuntu = False
863- self.assertTrue(tm1.is_current_ubuntu)
864- self.assertFalse(tm2.is_current_ubuntu)
865+ tm2.makeCurrentUbuntu(False)
866
867 self.potmsgset.updateTranslation(
868 self.pofile, self.uploader, [u"tm1"], lock_timestamp=self.now(),
869@@ -1184,7 +1195,7 @@
870 tm2 = self.potmsgset.updateTranslation(
871 self.pofile, self.uploader, [u"tm2"], lock_timestamp=self.now(),
872 is_current_upstream=True, force_diverged=True)
873- tm2.is_current_ubuntu = False
874+ tm2.makeCurrentUbuntu(False)
875
876 self.assertEquals(None, tm1.potemplate)
877 self.assertEquals(self.pofile.potemplate, tm2.potemplate)
878@@ -1249,10 +1260,11 @@
879 class TestPOTMsgSetTranslationCredits(TestCaseWithFactory):
880 """Test methods related to TranslationCredits."""
881
882- layer = ZopelessDatabaseLayer
883+ layer = DatabaseFunctionalLayer
884
885 def setUp(self):
886- super(TestPOTMsgSetTranslationCredits, self).setUp()
887+ super(TestPOTMsgSetTranslationCredits, self).setUp(
888+ 'carlos@canonical.com')
889 self.potemplate = self.factory.makePOTemplate()
890
891 def test_creation_credits(self):
892@@ -1368,10 +1380,8 @@
893 """Set up `KarmaRecorder` on `pofile`."""
894 template = pofile.potemplate
895 return self.installKarmaRecorder(
896- person=template.owner,
897- action_name='translationsuggestionadded',
898- product=template.product,
899- distribution=template.distribution,
900+ person=template.owner, action_name='translationsuggestionadded',
901+ product=template.product, distribution=template.distribution,
902 sourcepackagename=template.sourcepackagename)
903
904 def test_new_suggestion(self):
905@@ -1571,7 +1581,10 @@
906
907
908 class TestSetCurrentTranslation(TestCaseWithFactory):
909- layer = ZopelessDatabaseLayer
910+ layer = DatabaseFunctionalLayer
911+
912+ def setUp(self):
913+ super(TestSetCurrentTranslation, self).setUp('carlos@canonical.com')
914
915 def _makePOFileAndPOTMsgSet(self):
916 pofile = self.factory.makePOFile('nl')
917@@ -1599,62 +1612,62 @@
918 pofile.potemplate, pofile.language))
919 self.assertEqual(origin, message.origin)
920
921- def test_make_translation_side_message_traits(self):
922- # make_translation_side_message_traits is a factory for traits
923- # objects that help setCurrentTranslations deal with the
924- # dichotomy between upstream and Ubuntu translations.
925+ def test_make_message_side_helpers(self):
926+ # make_message_side_helpers is a factory for helpers that help
927+ # setCurrentTranslations deal with the dichotomy between
928+ # upstream and Ubuntu translations.
929 pofile, potmsgset = self._makePOFileAndPOTMsgSet()
930 sides = (TranslationSide.UPSTREAM, TranslationSide.UBUNTU)
931 for side in sides:
932- traits = make_translation_side_message_traits(
933+ helper = make_message_side_helpers(
934 side, potmsgset, pofile.potemplate, pofile.language)
935- self.assertEqual(side, traits.side)
936- self.assertNotEqual(side, traits.other_side.side)
937- self.assertIn(traits.other_side.side, sides)
938- self.assertIs(traits, traits.other_side.other_side)
939+ self.assertEqual(side, helper.traits.side)
940+ self.assertNotEqual(side, helper.other_side.traits.side)
941+ self.assertIn(helper.other_side.traits.side, sides)
942+ self.assertIs(helper, helper.other_side.other_side)
943
944 def test_UpstreamSideTraits_upstream(self):
945 pofile, potmsgset = self._makePOFileAndPOTMsgSet()
946 message = self.factory.makeTranslationMessage(
947 pofile=pofile, potmsgset=potmsgset)
948
949- traits = make_translation_side_message_traits(
950+ helper = make_message_side_helpers(
951 TranslationSide.UPSTREAM, potmsgset, pofile.potemplate,
952 pofile.language)
953
954- self.assertEqual('is_current_upstream', traits.flag_name)
955+ self.assertEqual('is_current_upstream', helper.traits.flag_name)
956
957- self.assertFalse(traits.getFlag(message))
958+ self.assertFalse(helper.traits.getFlag(message))
959 self.assertFalse(message.is_current_upstream)
960- self.assertEquals(None, traits.incumbent_message)
961-
962- traits.setFlag(message, True)
963-
964- self.assertTrue(traits.getFlag(message))
965+ self.assertEquals(None, helper.incumbent_message)
966+
967+ helper.setFlag(message, True)
968+
969+ self.assertTrue(helper.traits.getFlag(message))
970 self.assertTrue(message.is_current_upstream)
971- self.assertEquals(message, traits.incumbent_message)
972+ self.assertEquals(message, helper.incumbent_message)
973
974 def test_UpstreamSideTraits_ubuntu(self):
975 pofile, potmsgset = self._makePOFileAndPOTMsgSet()
976 message = self.factory.makeTranslationMessage(
977 pofile=pofile, potmsgset=potmsgset)
978- message.is_current_ubuntu = False
979+ message.makeCurrentUbuntu(False)
980
981- traits = make_translation_side_message_traits(
982+ helper = make_message_side_helpers(
983 TranslationSide.UBUNTU, potmsgset, pofile.potemplate,
984 pofile.language)
985
986- self.assertEqual('is_current_ubuntu', traits.flag_name)
987+ self.assertEqual('is_current_ubuntu', helper.traits.flag_name)
988
989- self.assertFalse(traits.getFlag(message))
990+ self.assertFalse(helper.traits.getFlag(message))
991 self.assertFalse(message.is_current_ubuntu)
992- self.assertEquals(None, traits.incumbent_message)
993-
994- traits.setFlag(message, True)
995-
996- self.assertTrue(traits.getFlag(message))
997+ self.assertEquals(None, helper.incumbent_message)
998+
999+ helper.setFlag(message, True)
1000+
1001+ self.assertTrue(helper.traits.getFlag(message))
1002 self.assertTrue(message.is_current_ubuntu)
1003- self.assertEquals(message, traits.incumbent_message)
1004+ self.assertEquals(message, helper.incumbent_message)
1005
1006 def test_identical(self):
1007 # Setting the same message twice leaves the original as-is.
1008
1009=== modified file 'lib/lp/translations/tests/test_setcurrenttranslation.py'
1010--- lib/lp/translations/tests/test_setcurrenttranslation.py 2010-07-06 09:27:37 +0000
1011+++ lib/lp/translations/tests/test_setcurrenttranslation.py 2010-08-06 07:43:48 +0000
1012@@ -13,8 +13,7 @@
1013 from lp.testing import TestCaseWithFactory
1014 from lp.translations.interfaces.translationmessage import (
1015 RosettaTranslationOrigin)
1016-from lp.translations.interfaces.translations import (
1017- TranslationSide)
1018+from lp.translations.interfaces.side import TranslationSide
1019 from lp.translations.model.translationmessage import (
1020 TranslationMessage)
1021
1022@@ -87,7 +86,8 @@
1023 * current: represents a current shared translation for this context.
1024 * diverged: represents a diverged translation for this context.
1025 * other_shared: represents a shared translation for "other" context.
1026- * divergences_elsewhere: a list of other divergences in both contexts.
1027+ * divergences_elsewhere: a list of other divergences in both
1028+ contexts.
1029 """
1030 new_current, new_diverged, new_other, new_divergences = (
1031 summarize_current_translations(self.pofile, self.potmsgset))
1032
1033=== added file 'lib/lp/translations/tests/test_side.py'
1034--- lib/lp/translations/tests/test_side.py 1970-01-01 00:00:00 +0000
1035+++ lib/lp/translations/tests/test_side.py 2010-08-06 07:43:48 +0000
1036@@ -0,0 +1,186 @@
1037+# Copyright 2010 Canonical Ltd. This software is licensed under the
1038+# GNU Affero General Public License version 3 (see the file LICENSE).
1039+
1040+"""Test `TranslationSide` and friends."""
1041+
1042+__metaclass__ = type
1043+
1044+from canonical.testing import DatabaseFunctionalLayer
1045+from lp.testing import TestCaseWithFactory
1046+
1047+from zope.component import getUtility
1048+from zope.interface.verify import verifyObject
1049+
1050+from lp.translations.interfaces.side import (
1051+ ITranslationSideTraits,
1052+ ITranslationSideTraitsSet,
1053+ TranslationSide)
1054+
1055+
1056+class TestTranslationSideTraitsSet(TestCaseWithFactory):
1057+ layer = DatabaseFunctionalLayer
1058+
1059+ def test_baseline(self):
1060+ utility = getUtility(ITranslationSideTraitsSet)
1061+ self.assertTrue(verifyObject(ITranslationSideTraitsSet, utility))
1062+ for traits in utility.getAllTraits().itervalues():
1063+ self.assertTrue(verifyObject(ITranslationSideTraits, traits))
1064+
1065+ def test_other_sides(self):
1066+ utility = getUtility(ITranslationSideTraitsSet)
1067+ upstream = utility.getTraits(TranslationSide.UPSTREAM)
1068+ ubuntu = utility.getTraits(TranslationSide.UBUNTU)
1069+
1070+ self.assertEqual(ubuntu, upstream.other_side_traits)
1071+ self.assertEqual(upstream, ubuntu.other_side_traits)
1072+
1073+ def test_getTraits(self):
1074+ utility = getUtility(ITranslationSideTraitsSet)
1075+ for side in [TranslationSide.UPSTREAM, TranslationSide.UBUNTU]:
1076+ traits = utility.getTraits(side)
1077+ self.assertTrue(verifyObject(ITranslationSideTraits, traits))
1078+
1079+ def test_getForTemplate_upstream(self):
1080+ utility = getUtility(ITranslationSideTraitsSet)
1081+ productseries = self.factory.makeProductSeries()
1082+ template = self.factory.makePOTemplate(productseries=productseries)
1083+ traits = utility.getForTemplate(template)
1084+ self.assertEqual(TranslationSide.UPSTREAM, traits.side)
1085+
1086+ def test_getForTemplate_ubuntu(self):
1087+ utility = getUtility(ITranslationSideTraitsSet)
1088+ package = self.factory.makeSourcePackage()
1089+ template = self.factory.makePOTemplate(
1090+ distroseries=package.distroseries,
1091+ sourcepackagename=package.sourcepackagename)
1092+ traits = utility.getForTemplate(template)
1093+ self.assertEqual(TranslationSide.UBUNTU, traits.side)
1094+
1095+ def test_getAllTraits(self):
1096+ utility = getUtility(ITranslationSideTraitsSet)
1097+ traits_dict = utility.getAllTraits()
1098+
1099+ self.assertContentEqual(
1100+ [TranslationSide.UPSTREAM, TranslationSide.UBUNTU],
1101+ traits_dict.keys())
1102+
1103+ for side, traits in traits_dict.iteritems():
1104+ self.assertEqual(side, traits.side)
1105+ self.assertEqual(traits, utility.getTraits(side))
1106+
1107+
1108+class TraitsScenario:
1109+ """Tests that can be run on either the upstream or the Ubuntu side."""
1110+
1111+ def _makeTemplate(self):
1112+ """Create a template for the side being tested."""
1113+ raise NotImplementedError()
1114+
1115+ def _makeTemplateAndTranslationMessage(self):
1116+ """Create a POTemplate with a TranslationMessage.
1117+
1118+ Creates a POFile and POTMsgSet along the way.
1119+
1120+ The TranslationMessage will not be current.
1121+ """
1122+ template = self._makeTemplate()
1123+ pofile = self.factory.makePOFile('nl', template)
1124+ potmsgset = self.factory.makePOTMsgSet(template, sequence=1)
1125+ translationmessage = potmsgset.submitSuggestion(
1126+ pofile, self.factory.makePerson(),
1127+ [self.factory.getUniqueString()])
1128+ return template, translationmessage
1129+
1130+ def _getTraits(self, template):
1131+ """Shortcut: get TranslationSideTraits for template."""
1132+ return getUtility(ITranslationSideTraitsSet).getForTemplate(template)
1133+
1134+ def test_getFlag_and_setFlag(self):
1135+ template, message = self._makeTemplateAndTranslationMessage()
1136+ traits = self._getTraits(template)
1137+ other_side_traits = traits.other_side_traits
1138+
1139+ traits.setFlag(message, True)
1140+
1141+ self.assertEqual(
1142+ (True, False),
1143+ (traits.getFlag(message), other_side_traits.getFlag(message)))
1144+
1145+ traits.setFlag(message, False)
1146+
1147+ self.assertEqual(
1148+ (False, False),
1149+ (traits.getFlag(message), other_side_traits.getFlag(message)))
1150+
1151+ def test_getCurrentMessage(self):
1152+ template, message = self._makeTemplateAndTranslationMessage()
1153+ traits = self._getTraits(template)
1154+
1155+ traits.setFlag(message, True)
1156+
1157+ current_message = traits.getCurrentMessage(
1158+ message.potmsgset, template, message.language)
1159+ self.assertEqual(message, current_message)
1160+
1161+ traits.setFlag(message, False)
1162+
1163+ current_message = traits.getCurrentMessage(
1164+ message.potmsgset, template, message.language)
1165+ self.assertIs(None, current_message)
1166+
1167+ def test_getCurrentMessage_ignores_other_flag(self):
1168+ template, message = self._makeTemplateAndTranslationMessage()
1169+ traits = self._getTraits(template)
1170+ other_side_traits = traits.other_side_traits
1171+
1172+ other_side_traits.setFlag(message, True)
1173+
1174+ current_message = traits.getCurrentMessage(
1175+ message.potmsgset, template, message.language)
1176+ self.assertIs(None, current_message)
1177+
1178+ other_side_traits.setFlag(message, False)
1179+
1180+ current_message = traits.getCurrentMessage(
1181+ message.potmsgset, template, message.language)
1182+ self.assertIs(None, current_message)
1183+
1184+
1185+class UpstreamTranslationSideTraitsTest(TraitsScenario, TestCaseWithFactory):
1186+ """Run the TraitsScenario tests on the upstream side."""
1187+ layer = DatabaseFunctionalLayer
1188+
1189+ def _makeTemplate(self):
1190+ """See `TraitsScenario`."""
1191+ return self.factory.makePOTemplate(
1192+ productseries=self.factory.makeProductSeries())
1193+
1194+ def test_getFlag_reads_upstream_flag(self):
1195+ # This test case looks on the upstream side. We're really
1196+ # working with the is_current_upstream flag underneath the
1197+ # traits interface.
1198+ template, message = self._makeTemplateAndTranslationMessage()
1199+ traits = self._getTraits(template)
1200+ traits.setFlag(message, True)
1201+ self.assertTrue(message.is_current_upstream)
1202+
1203+
1204+class UbuntuTranslationSideTraitsTest(TraitsScenario, TestCaseWithFactory):
1205+ """Run the TraitsScenario tests on the Ubuntu side."""
1206+ layer = DatabaseFunctionalLayer
1207+
1208+ def _makeTemplate(self):
1209+ """See `TraitsScenario`."""
1210+ package = self.factory.makeSourcePackage()
1211+ return self.factory.makePOTemplate(
1212+ distroseries=package.distroseries,
1213+ sourcepackagename=package.sourcepackagename)
1214+
1215+ def test_getFlag_reads_ubuntu_flag(self):
1216+ # This test case looks on the Ubuntu side. We're really
1217+ # working with the is_current_ubuntu flag underneath the traits
1218+ # interface.
1219+ template, message = self._makeTemplateAndTranslationMessage()
1220+ traits = self._getTraits(template)
1221+ traits.setFlag(message, True)
1222+ self.assertTrue(message.is_current_ubuntu)

Subscribers

People subscribed via source and target branches