[Zope3-checkins] SVN: Zope3/trunk/src/zope/tal/ improve multiple domains i18n tests; fix tests; then fix interpreter

Godefroid Chapelle gotcha at bubblenet.be
Sat Sep 24 16:51:36 EDT 2005


Log message for revision 38603:
  improve multiple domains i18n tests; fix tests; then fix interpreter

Changed:
  U   Zope3/trunk/src/zope/tal/dummyengine.py
  U   Zope3/trunk/src/zope/tal/talinterpreter.py
  U   Zope3/trunk/src/zope/tal/tests/test_talinterpreter.py

-=-
Modified: Zope3/trunk/src/zope/tal/dummyengine.py
===================================================================
--- Zope3/trunk/src/zope/tal/dummyengine.py	2005-09-24 18:28:51 UTC (rev 38602)
+++ Zope3/trunk/src/zope/tal/dummyengine.py	2005-09-24 20:51:36 UTC (rev 38603)
@@ -265,6 +265,19 @@
 
     domain = ''
 
+    msgids = {} 
+
+    def appendMsgid(self, domain, data):
+        if not self.msgids.has_key(domain):
+            self.msgids[domain] = []
+        self.msgids[domain].append(data)    
+    
+    def getMsgids(self, domain):
+        return self.msgids[domain]
+
+    def clearMsgids(self):
+        self.msgids = {}
+
     def translate(self, msgid, mapping=None, context=None,
                   target_language=None, default=None):
 
@@ -293,94 +306,27 @@
         elif domain and hasattr('', domain):
             text = getattr(msgid, domain)()
         else:
+            domain = 'default'
             text = msgid.upper()
 
+        self.appendMsgid(domain, (msgid, mapping))
+        
         def repl(m):
             return unicode(mapping[m.group(m.lastindex).lower()])
         cre = re.compile(r'\$(?:([_A-Za-z][-\w]*)|\{([_A-Za-z][-\w]*)\})')
         return cre.sub(repl, text)
 
-
 class MultipleDomainsDummyEngine(DummyEngine):
     
-    def __init__(self, macros=None):
-        if macros is None:
-            macros = {}
-        self.macros = macros
-        dict = {'nothing': None, 'default': Default}
-        self.locals = self.globals = dict
-        self.stack = [dict]
-        self.translationDomain = DummyTranslationDomain()
-        self.lowerDomain = LowerDummyDomain()
-        self.useEngineAttrDicts = False
-
     def translate(self, msgid, domain=None, mapping=None, default=None):
+        
         if isinstance(msgid, (MessageID, Message)):
             domain = msgid.domain
-        if domain in ['lower', 'a_very_explicit_domain_setup_by_template_developer_that_wont_be_taken_into_account_by_the_ZPT_engine']:
-            translationDomain = self.lowerDomain
-        else:
-            translationDomain = self.translationDomain
-        translationDomain.domain = domain
-        return translationDomain.translate(
+        
+        if domain == 'a_very_explicit_domain_setup_by_template_developer_that_wont_be_taken_into_account_by_the_ZPT_engine':
+            domain = 'lower'
+        
+        self.translationDomain.domain = domain
+        return self.translationDomain.translate(
             msgid, mapping, default=default)
 
-class LowerDummyDomain(object):
-    implements(ITranslationDomain)
-
-    domain = ''
-
-    def translate(self, msgid, mapping=None, context=None,
-                  target_language=None, default=None):
-
-        domain = self.domain
-        # This is a fake translation service which simply uppercases non
-        # ${name} placeholder text in the message id.
-        #
-        # First, transform a string with ${name} placeholders into a list of
-        # substrings.  Then lowcase everything but the placeholders, then glue
-        # things back together.
-
-        # If the domain is a string method, then transform the string
-        # by calling that method.
-
-        # MessageID attributes override arguments
-        if isinstance(msgid, (MessageID, Message)):
-            domain = msgid.domain
-            mapping = msgid.mapping
-            default = msgid.default
-            if default is None: # Message doesn't substitute itself for
-                default = msgid # missing default
-
-        # simulate an unknown msgid by returning None
-        if msgid == "don't translate me":
-            text = default
-        elif domain and hasattr('', domain):
-            text = getattr(msgid, domain)()
-        else:
-            text = msgid.lower()
-
-        def repl(m):
-            return unicode(mapping[m.group(m.lastindex).lower()])
-        cre = re.compile(r'\$(?:([_A-Za-z][-\w]*)|\{([_A-Za-z][-\w]*)\})')
-        return cre.sub(repl, text)
-
-    def translate(self, msgid, mapping=None, context=None,
-                  target_language=None, default=None):
-        # This is a fake translation service which simply lowercases non
-        # ${name} placeholder text in the message id.
-        #
-        # First, transform a string with ${name} placeholders into a list of
-        # substrings.  Then upcase everything but the placeholders, then glue
-        # things back together.
-
-        # simulate an unknown msgid by returning None
-        if msgid == "don't translate me":
-            text = default
-        else:
-            text = msgid.lower()
-
-        def repl(m, mapping=mapping):
-            return ustr(mapping[m.group(m.lastindex).lower()])
-        cre = re.compile(r'\$(?:(%s)|\{(%s)\})' % (NAME_RE, NAME_RE))
-        return cre.sub(repl, text)

Modified: Zope3/trunk/src/zope/tal/talinterpreter.py
===================================================================
--- Zope3/trunk/src/zope/tal/talinterpreter.py	2005-09-24 18:28:51 UTC (rev 38602)
+++ Zope3/trunk/src/zope/tal/talinterpreter.py	2005-09-24 20:51:36 UTC (rev 38603)
@@ -19,6 +19,8 @@
 import operator
 import sys
 
+from types import StringType, UnicodeType
+
 # Do not use cStringIO here!  It's not unicode aware. :(
 from StringIO import StringIO
 
@@ -651,6 +653,8 @@
             return
         if isinstance(text, I18nMessageTypes):
             text = self.engine.translate(text)
+        elif isinstance(text, (StringType, UnicodeType)):
+            text = self.engine.translate(text, domain=self.i18nContext.domain)
         self._writeText(text)
 
     def do_i18nVariable(self, stuff):

Modified: Zope3/trunk/src/zope/tal/tests/test_talinterpreter.py
===================================================================
--- Zope3/trunk/src/zope/tal/tests/test_talinterpreter.py	2005-09-24 18:28:51 UTC (rev 38602)
+++ Zope3/trunk/src/zope/tal/tests/test_talinterpreter.py	2005-09-24 20:51:36 UTC (rev 38603)
@@ -22,9 +22,6 @@
 
 from StringIO import StringIO
 
-from zope.interface import implements
-from zope.i18n.interfaces import ITranslationDomain
-
 from zope.tal.taldefs import METALError, I18NError, TAL_VERSION
 from zope.tal.htmltalparser import HTMLTALParser
 from zope.tal.talparser import TALParser
@@ -127,10 +124,6 @@
         self.assertEqual(actual, expected)
 
 
-
-
-
-
 class I18NCornerTestCaseBase(TestCaseBase):
 
     def factory(self, msgid, default, mapping={}):
@@ -221,10 +214,16 @@
     def test_translate_static_text_as_dynamic(self):
         program, macros = self._compile(
             '<div i18n:translate="">This is text for '
+            '<span tal:content="bar" i18n:name="bar_name"/>.'
+            '</div>')
+        self._check(program,
+                    '<div>THIS IS TEXT FOR <span>BaRvAlUe</span>.</div>\n')
+        program, macros = self._compile(
+            '<div i18n:translate="">This is text for '
             '<span i18n:translate="" tal:content="bar" i18n:name="bar_name"/>.'
             '</div>')
         self._check(program,
-                    '<div>THIS IS TEXT FOR <span>BaRvAlUe</span>.</div>\n')
+                    '<div>THIS IS TEXT FOR <span>BARVALUE</span>.</div>\n')
 
     def test_translate_static_text_as_dynamic_from_bytecode(self):
         program =  [('version', TAL_VERSION),
@@ -259,32 +258,24 @@
         self._check(program,
                     '<div>THIS IS TEXT FOR <span>BARVALUE</span>.</div>\n')
 
-    def _getCollectingTranslationDomain(self):
-        class CollectingTranslationDomain(DummyTranslationDomain):
-            data = []
-
-            def translate(self, msgid, mapping=None,
-                          context=None, target_language=None, default=None):
-                self.data.append((msgid, mapping))
-                return DummyTranslationDomain.translate(
-                    self,
-                    msgid, mapping, context, target_language, default)
-
-        xlatdmn = CollectingTranslationDomain()
-        self.engine.translationDomain = xlatdmn
-        return xlatdmn
-
     def test_for_correct_msgids(self):
-        xlatdmn = self._getCollectingTranslationDomain()
+        self.engine.translationDomain.clearMsgids()
         result = StringIO()
+        #GChapelle: 
+        #I have the feeling the i18n:translate with the i18n:name is wrong
+        #
+        #program, macros = self._compile(
+        #    '<div i18n:translate="">This is text for '
+        #    '<span i18n:translate="" tal:content="bar" '
+        #    'i18n:name="bar_name"/>.</div>')
         program, macros = self._compile(
             '<div i18n:translate="">This is text for '
-            '<span i18n:translate="" tal:content="bar" '
+            '<span tal:content="bar" '
             'i18n:name="bar_name"/>.</div>')
         self.interpreter = TALInterpreter(program, {}, self.engine,
                                           stream=result)
         self.interpreter()
-        msgids = list(xlatdmn.data)
+        msgids = self.engine.translationDomain.getMsgids('default')
         msgids.sort()
         self.assertEqual(1, len(msgids))
         self.assertEqual('This is text for ${bar_name}.', msgids[0][0])
@@ -293,10 +284,29 @@
             '<div>THIS IS TEXT FOR <span>BaRvAlUe</span>.</div>\n',
             result.getvalue())
 
+    def test_for_correct_msgids_translate_name(self):
+        self.engine.translationDomain.clearMsgids()
+        result = StringIO()
+        program, macros = self._compile(
+            '<div i18n:translate="">This is text for '
+            '<span i18n:translate="" tal:content="bar" '
+            'i18n:name="bar_name"/>.</div>')
+        self.interpreter = TALInterpreter(program, {}, self.engine,
+                                          stream=result)
+        self.interpreter()
+        msgids = self.engine.translationDomain.getMsgids('default')
+        msgids.sort()
+        self.assertEqual(2, len(msgids))
+        self.assertEqual('This is text for ${bar_name}.', msgids[1][0])
+        self.assertEqual({'bar_name': '<span>BARVALUE</span>'}, msgids[1][1])
+        self.assertEqual(
+            '<div>THIS IS TEXT FOR <span>BARVALUE</span>.</div>\n',
+            result.getvalue())
+
     def test_i18ntranslate_i18nname_and_attributes(self):
         # Test for Issue 301: Bug with i18n:name and i18n:translate
         # on the same element
-        xlatdmn = self._getCollectingTranslationDomain()
+        self.engine.translationDomain.clearMsgids()
         result = StringIO()
         program, macros = self._compile(
             '<p i18n:translate="">'
@@ -305,7 +315,7 @@
         self.interpreter = TALInterpreter(program, {}, self.engine,
                                           stream=result)
         self.interpreter()
-        msgids = list(xlatdmn.data)
+        msgids = self.engine.translationDomain.getMsgids('default')
         msgids.sort()
         self.assertEqual(2, len(msgids))
         self.assertEqual('Some static text and a ${link}.', msgids[0][0])
@@ -319,7 +329,7 @@
         # Test for Issue 314: i18n:translate removes line breaks from
         # <pre>...</pre> contents
         # HTML mode
-        xlatdmn = self._getCollectingTranslationDomain()
+        self.engine.translationDomain.clearMsgids()
         result = StringIO()
         program, macros = self._compile(
             '<div i18n:translate=""> This is text\n'
@@ -329,7 +339,7 @@
         self.interpreter = TALInterpreter(program, {}, self.engine,
                                           stream=result)
         self.interpreter()
-        msgids = list(xlatdmn.data)
+        msgids = self.engine.translationDomain.getMsgids('default')
         msgids.sort()
         self.assertEqual(2, len(msgids))
         self.assertEqual(' This is text\n <b>\tfor</b>\n pre. ', msgids[0][0])
@@ -340,7 +350,7 @@
             result.getvalue())
 
         # XML mode
-        xlatdmn = self._getCollectingTranslationDomain()
+        self.engine.translationDomain.clearMsgids()
         result = StringIO()
         parser = TALParser()
         parser.parseString(
@@ -352,7 +362,7 @@
         self.interpreter = TALInterpreter(program, {}, self.engine,
                                           stream=result)
         self.interpreter()
-        msgids = list(xlatdmn.data)
+        msgids = self.engine.translationDomain.getMsgids('default')
         msgids.sort()
         self.assertEqual(1, len(msgids))
         self.assertEqual('This is text <b> for</b> barvalue.', msgids[0][0])
@@ -362,7 +372,7 @@
             result.getvalue())
 
     def test_raw_msgids_and_i18ntranslate_i18nname(self):
-        xlatdmn = self._getCollectingTranslationDomain()
+        self.engine.translationDomain.clearMsgids()
         result = StringIO()
         program, macros = self._compile(
             '<div i18n:translate=""> This is text\n \tfor\n'
@@ -370,7 +380,7 @@
         self.interpreter = TALInterpreter(program, {}, self.engine,
                                           stream=result)
         self.interpreter()
-        msgids = list(xlatdmn.data)
+        msgids = self.engine.translationDomain.getMsgids('default')
         msgids.sort()
         self.assertEqual(2, len(msgids))
         self.assertEqual(' \tbar\n ', msgids[0][0])
@@ -405,20 +415,19 @@
 
     
     def setUp(self):
+        # MultipleDomainsDummyEngine is a Engine
+        # where default domain transforms to uppercase
         self.engine = MultipleDomainsDummyEngine()
-        # Make sure we'll translate the msgid not its unicode representation
         self.engine.setLocal('foo',
             self.factory('FoOvAlUe${empty}', 'default', {'empty': ''}))
         self.engine.setLocal('bar', 'BaRvAlUe')
         self.engine.setLocal('baz',
             self.factory('BaZvAlUe', 'default', {}))
         # Message ids with different domains
+        self.engine.setLocal('toupper',
+            self.factory('ToUpper', 'default', {}))
         self.engine.setLocal('tolower',
             self.factory('ToLower', 'default', {}, domain='lower'))
-        self.engine.setLocal('toupper',
-            self.factory('ToUpper', 'default', {}))
-        self.engine.setLocal('othertolower',
-            self.factory('OtherToLower', 'a_very_explicit_domain_setup_by_template_developer_that_wont_be_taken_into_account_by_the_ZPT_engine', {}, domain='lower'))
 
     def test_multiple_domains(self):
         program, macros = self._compile(
@@ -431,14 +440,33 @@
         self._check(program, '<div>tolower</div>\n')
         program, macros = self._compile(
             '<div i18n:translate=""'
-            '     tal:content="othertolower" />')
-        self._check(program, '<div>othertolower</div>\n')
+            '     tal:content="string:ToUpper" />')
+        self._check(program, '<div>TOUPPER</div>\n')
+        program, macros = self._compile(
+            '<div i18n:translate=""'
+            '     i18n:domain="lower"'
+            '     tal:content="string:ToLower" />')
+        self._check(program, '<div>tolower</div>\n')
 
-
     def test_unused_explicit_domain(self):
+        #a_very_explicit_domain_setup_by_template_developer_that_wont_be_taken_into_account_by_the_ZPT_engine 
+        #is a domain that transforms to lowercase
+        self.engine.setLocal('othertolower',
+            self.factory('OtherToLower', 'a_very_explicit_domain_setup_by_template_developer_that_wont_be_taken_into_account_by_the_ZPT_engine', {}, domain='lower'))
         program, macros = self._compile(
             '<div i18n:translate=""'
+            '     tal:content="othertolower" />')
+        self._check(program, '<div>othertolower</div>\n')
+        #takes domain into account for strings
+        program, macros = self._compile(
+            '<div i18n:translate=""'
             '     i18n:domain="a_very_explicit_domain_setup_by_template_developer_that_wont_be_taken_into_account_by_the_ZPT_engine"'
+            '     tal:content="string:ToLower" />')
+        self._check(program, '<div>tolower</div>\n')
+        #but not for messageids
+        program, macros = self._compile(
+            '<div i18n:translate=""'
+            '     i18n:domain="a_very_explicit_domain_setup_by_template_developer_that_wont_be_taken_into_account_by_the_ZPT_engine"'
             '     tal:content="baz" />')
         self._check(program, '<div>BAZVALUE</div>\n')
 



More information about the Zope3-Checkins mailing list