Edgewall Software

Ticket #129: i18n_directives_full_with_py_strip.patch

File i18n_directives_full_with_py_strip.patch, 85.2 KB (added by palgarvio, 5 months ago)
  • genshi/filters/tests/i18n.py

     
    1313 
    1414from datetime import datetime 
    1515import doctest 
    16 from gettext import NullTranslations 
     16from gettext import NullTranslations, c2py 
    1717from StringIO import StringIO 
    1818import unittest 
    1919 
    2020from genshi.core import Attrs 
    2121from genshi.template import MarkupTemplate 
    22 from genshi.filters.i18n import Translator, extract 
     22from genshi.filters.i18n import Translator, extract, setup_i18n 
    2323from genshi.input import HTML 
    2424 
    2525 
    2626class DummyTranslations(NullTranslations): 
     27    _domains = {} 
    2728 
    28     def __init__(self, catalog): 
     29    def __init__(self, catalog=()): 
    2930        NullTranslations.__init__(self) 
    30         self._catalog = catalog 
     31        self._catalog = catalog or {} 
     32        self.plural = c2py('(n != 1)') 
     33         
     34    def add_domain(self, domain, catalog): 
     35        translation = DummyTranslations(catalog) 
     36        translation.add_fallback(self) 
     37        self._domains[domain] = translation 
     38         
     39    def _domain_call(self, func, domain, *args, **kwargs): 
     40        return getattr(self._domains.get(domain, self), func)(*args, **kwargs) 
    3141 
    3242    def ugettext(self, message): 
    3343        missing = object() 
     
    3747                return self._fallback.ugettext(message) 
    3848            return unicode(message) 
    3949        return tmsg 
     50     
     51    def dugettext(self, domain, message): 
     52        return self._domain_call('ugettext', domain, message) 
     53     
     54    def ungettext(self, msgid1, msgid2, n): 
     55        try: 
     56            return self._catalog[(msgid1, self.plural(n))] 
     57        except KeyError: 
     58            if self._fallback: 
     59                return self._fallback.ngettext(msgid1, msgid2, n) 
     60            if n == 1: 
     61                return msgid1 
     62            else: 
     63                return msgid2 
     64             
     65    def dungettext(self, domain, singular, plural, numeral): 
     66        return self._domain_call('ungettext', domain, singular, plural, numeral) 
    4067 
    4168 
    4269class TranslatorTestCase(unittest.TestCase): 
     
    162189          </p> 
    163190        </html>""") 
    164191        translator = Translator() 
     192        tmpl.add_directives(Translator.NAMESPACE, translator) 
    165193        messages = list(translator.extract(tmpl.stream)) 
    166194        self.assertEqual(1, len(messages)) 
    167195        self.assertEqual('Please see [1:Help] for details.', messages[0][2]) 
     
    175203        </html>""") 
    176204        gettext = lambda s: u"Für Details siehe bitte [1:Hilfe]." 
    177205        translator = Translator(gettext) 
    178         tmpl.filters.insert(0, translator) 
    179         tmpl.add_directives(Translator.NAMESPACE, translator) 
     206        setup_i18n(tmpl, translator) 
    180207        self.assertEqual("""<html> 
    181208          <p>Für Details siehe bitte <a href="help.html">Hilfe</a>.</p> 
    182209        </html>""", tmpl.generate().render()) 
     
    189216          </p> 
    190217        </html>""") 
    191218        translator = Translator() 
     219        tmpl.add_directives(Translator.NAMESPACE, translator) 
    192220        messages = list(translator.extract(tmpl.stream)) 
    193221        self.assertEqual(1, len(messages)) 
    194222        self.assertEqual('Please see [1:[2:Help] page] for details.', 
     
    203231        </html>""") 
    204232        gettext = lambda s: u"Für Details siehe bitte [1:[2:Hilfeseite]]." 
    205233        translator = Translator(gettext) 
    206         tmpl.filters.insert(0, translator) 
    207         tmpl.add_directives(Translator.NAMESPACE, translator) 
     234        setup_i18n(tmpl, translator) 
    208235        self.assertEqual("""<html> 
    209236          <p>Für Details siehe bitte <a href="help.html"><em>Hilfeseite</em></a>.</p> 
    210237        </html>""", tmpl.generate().render()) 
     
    217244          </p> 
    218245        </html>""") 
    219246        translator = Translator() 
     247        tmpl.add_directives(Translator.NAMESPACE, translator) 
    220248        messages = list(translator.extract(tmpl.stream)) 
    221249        self.assertEqual(1, len(messages)) 
    222250        self.assertEqual('Show me [1:] entries per page.', messages[0][2]) 
     
    230258        </html>""") 
    231259        gettext = lambda s: u"[1:] Einträge pro Seite anzeigen." 
    232260        translator = Translator(gettext) 
    233         tmpl.filters.insert(0, translator) 
    234         tmpl.add_directives(Translator.NAMESPACE, translator) 
     261        setup_i18n(tmpl, translator) 
    235262        self.assertEqual("""<html> 
    236263          <p><input type="text" name="num"/> Einträge pro Seite anzeigen.</p> 
    237264        </html>""", tmpl.generate().render()) 
     
    244271          </p> 
    245272        </html>""") 
    246273        translator = Translator() 
     274        tmpl.add_directives(Translator.NAMESPACE, translator) 
    247275        messages = list(translator.extract(tmpl.stream)) 
    248276        self.assertEqual(1, len(messages)) 
    249277        self.assertEqual('Please see [1:Help] for [2:details].', messages[0][2]) 
     
    257285        </html>""") 
    258286        gettext = lambda s: u"Für [2:Details] siehe bitte [1:Hilfe]." 
    259287        translator = Translator(gettext) 
    260         tmpl.filters.insert(0, translator) 
    261         tmpl.add_directives(Translator.NAMESPACE, translator) 
     288        setup_i18n(tmpl, translator) 
    262289        self.assertEqual("""<html> 
    263290          <p>Für <em>Details</em> siehe bitte <a href="help.html">Hilfe</a>.</p> 
    264291        </html>""", tmpl.generate().render()) 
     
    271298          </p> 
    272299        </html>""") 
    273300        translator = Translator() 
     301        tmpl.add_directives(Translator.NAMESPACE, translator) 
    274302        messages = list(translator.extract(tmpl.stream)) 
    275303        self.assertEqual(1, len(messages)) 
    276304        self.assertEqual('Show me [1:] entries per page, starting at page [2:].', 
     
    285313        </html>""") 
    286314        gettext = lambda s: u"[1:] Einträge pro Seite, beginnend auf Seite [2:]." 
    287315        translator = Translator(gettext) 
    288         tmpl.filters.insert(0, translator) 
    289         tmpl.add_directives(Translator.NAMESPACE, translator) 
     316        setup_i18n(tmpl, translator) 
    290317        self.assertEqual("""<html> 
    291318          <p><input type="text" name="num"/> Eintr\xc3\xa4ge pro Seite, beginnend auf Seite <input type="text" name="num"/>.</p> 
    292319        </html>""", tmpl.generate().render()) 
     
    299326          </p> 
    300327        </html>""") 
    301328        translator = Translator() 
     329        tmpl.add_directives(Translator.NAMESPACE, translator) 
    302330        messages = list(translator.extract(tmpl.stream)) 
    303331        self.assertEqual(1, len(messages)) 
    304332        self.assertEqual('Hello, %(name)s!', messages[0][2]) 
     
    312340        </html>""") 
    313341        gettext = lambda s: u"Hallo, %(name)s!" 
    314342        translator = Translator(gettext) 
    315         tmpl.filters.insert(0, translator) 
    316         tmpl.add_directives(Translator.NAMESPACE, translator) 
     343        setup_i18n(tmpl, translator) 
    317344        self.assertEqual("""<html> 
    318345          <p>Hallo, Jim!</p> 
    319346        </html>""", tmpl.generate(user=dict(name='Jim')).render()) 
     
    327354        </html>""") 
    328355        gettext = lambda s: u"%(name)s, sei gegrüßt!" 
    329356        translator = Translator(gettext) 
    330         tmpl.filters.insert(0, translator) 
    331         tmpl.add_directives(Translator.NAMESPACE, translator) 
     357        setup_i18n(tmpl, translator) 
    332358        self.assertEqual("""<html> 
    333359          <p>Jim, sei gegrüßt!</p> 
    334360        </html>""", tmpl.generate(user=dict(name='Jim')).render()) 
     
    342368        </html>""") 
    343369        gettext = lambda s: u"Sei gegrüßt, [1:Alter]!" 
    344370        translator = Translator(gettext) 
    345         tmpl.filters.insert(0, translator) 
    346         tmpl.add_directives(Translator.NAMESPACE, translator) 
     371        setup_i18n(tmpl, translator) 
    347372        self.assertEqual("""<html> 
    348373          <p>Sei gegrüßt, <a href="#42">Alter</a>!</p> 
    349374        </html>""", tmpl.generate(anchor='42').render()) 
     
    356381          </p> 
    357382        </html>""") 
    358383        translator = Translator() 
     384        tmpl.add_directives(Translator.NAMESPACE, translator) 
    359385        messages = list(translator.extract(tmpl.stream)) 
    360386        self.assertEqual(1, len(messages)) 
    361387        self.assertEqual('Posted by %(name)s at %(time)s', messages[0][2]) 
     
    369395        </html>""") 
    370396        gettext = lambda s: u"%(name)s schrieb dies um %(time)s" 
    371397        translator = Translator(gettext) 
    372         tmpl.filters.insert(0, translator) 
    373         tmpl.add_directives(Translator.NAMESPACE, translator) 
     398        setup_i18n(tmpl, translator) 
    374399        entry = { 
    375400            'author': 'Jim', 
    376401            'time': datetime(2008, 4, 1, 14, 30) 
     
    387412          </p> 
    388413        </html>""") 
    389414        translator = Translator() 
     415        tmpl.add_directives(Translator.NAMESPACE, translator) 
    390416        messages = list(translator.extract(tmpl.stream)) 
    391417        self.assertEqual(1, len(messages)) 
    392418        self.assertEqual('Show me [1:] entries per page.', messages[0][2]) 
    393419 
    394     # FIXME: this currently fails :-/ 
    395 #    def test_translate_i18n_msg_with_directive(self): 
    396 #        tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/" 
    397 #            xmlns:i18n="http://genshi.edgewall.org/i18n"> 
    398 #          <p i18n:msg=""> 
    399 #            Show me <input type="text" name="num" py:attrs="{'value': x}" /> entries per page. 
    400 #          </p> 
    401 #        </html>""") 
    402 #        gettext = lambda s: u"[1:] Einträge pro Seite anzeigen." 
    403 #        tmpl.filters.insert(0, Translator(gettext)) 
    404 #        self.assertEqual("""<html> 
    405 #          <p><input type="text" name="num" value="x"/> Einträge pro Seite anzeigen.</p> 
    406 #        </html>""", tmpl.generate().render()) 
     420    def test_translate_i18n_msg_with_directive(self): 
     421        tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/" 
     422            xmlns:i18n="http://genshi.edgewall.org/i18n"> 
     423          <p i18n:msg=""> 
     424            Show me <input type="text" name="num" py:attrs="{'value': 'x'}" /> entries per page. 
     425          </p> 
     426        </html>""") 
     427        gettext = lambda s: u"[1:] Einträge pro Seite anzeigen." 
     428        translator = Translator(gettext) 
     429        setup_i18n(tmpl, translator) 
     430        self.assertEqual("""<html> 
     431          <p><input type="text" name="num" value="x"/> Einträge pro Seite anzeigen.</p> 
     432        </html>""", tmpl.generate().render()) 
    407433 
    408434    def test_extract_i18n_msg_with_comment(self): 
    409435        tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/" 
    410436            xmlns:i18n="http://genshi.edgewall.org/i18n"> 
     437          <p i18n:comment="As in foo bar" i18n:msg="">Foo</p> 
     438        </html>""") 
     439        translator = Translator() 
     440        tmpl.add_directives(Translator.NAMESPACE, translator) 
     441        messages = list(translator.extract(tmpl.stream)) 
     442        self.assertEqual(1, len(messages)) 
     443        self.assertEqual((3, None, u'Foo', ['As in foo bar']), messages[0]) 
     444        tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/" 
     445            xmlns:i18n="http://genshi.edgewall.org/i18n"> 
    411446          <p i18n:msg="" i18n:comment="As in foo bar">Foo</p> 
    412447        </html>""") 
    413448        translator = Translator() 
     449        tmpl.add_directives(Translator.NAMESPACE, translator) 
    414450        messages = list(translator.extract(tmpl.stream)) 
    415451        self.assertEqual(1, len(messages)) 
    416452        self.assertEqual((3, None, u'Foo', ['As in foo bar']), messages[0]) 
     
    422458        </html>""") 
    423459        gettext = lambda s: u"Voh" 
    424460        translator = Translator(gettext) 
    425         tmpl.filters.insert(0, translator) 
    426         tmpl.add_directives(Translator.NAMESPACE, translator) 
     461        setup_i18n(tmpl, translator) 
    427462        self.assertEqual("""<html> 
    428463          <p>Voh</p> 
    429464        </html>""", tmpl.generate().render()) 
     
    461496          <p i18n:msg="" i18n:comment="As in foo bar">Foo</p> 
    462497        </html>""") 
    463498        translator = Translator(DummyTranslations({'Foo': 'Voh'})) 
    464         tmpl.filters.insert(0, translator) 
    465         tmpl.add_directives(Translator.NAMESPACE, translator) 
     499        setup_i18n(tmpl, translator) 
    466500        self.assertEqual("""<html> 
    467501          <p>Voh</p> 
    468502        </html>""", tmpl.generate().render()) 
     503         
     504    def test_translate_mixing_py_and_i18n_directives(self): 
     505        tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/" 
     506            xmlns:i18n="http://genshi.edgewall.org/i18n"> 
     507          <p i18n:msg="" i18n:comment="As in foo bar" py:strip="">Foo</p> 
     508          <p py:strip="" i18n:msg="" i18n:comment="As in foo bar">Foo</p> 
     509        </html>""") 
     510        translator = Translator(DummyTranslations({'Foo': 'Voh'})) 
     511        setup_i18n(tmpl, translator) 
     512        self.assertEqual("""<html> 
     513          Voh 
     514          Voh 
     515        </html>""", tmpl.generate().render()) 
     516         
     517    def test_translate_i18n_domain_with_msg_directives(self): 
     518        #"""translate with i18n:domain and nested i18n:msg directives """ 
    469519 
     520        tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/" 
     521            xmlns:i18n="http://genshi.edgewall.org/i18n"> 
     522          <div i18n:domain="foo"> 
     523            <p i18n:msg="">FooBar</p> 
     524            <p i18n:msg="">Bar</p> 
     525          </div> 
     526        </html>""") 
     527        translations = DummyTranslations({'Bar': 'Voh'}) 
     528        translations.add_domain('foo', {'FooBar': 'BarFoo', 'Bar': 'PT_Foo'}) 
     529        translator = Translator(translations) 
     530        setup_i18n(tmpl, translator) 
     531        self.assertEqual("""<html> 
     532          <div> 
     533            <p>BarFoo</p> 
     534            <p>PT_Foo</p> 
     535          </div> 
     536        </html>""", tmpl.generate().render()) 
     537         
     538    def test_translate_i18n_domain_with_inline_directives(self): 
     539        #"""translate with inlined i18n:domain and i18n:msg directives""" 
     540        tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/" 
     541            xmlns:i18n="http://genshi.edgewall.org/i18n"> 
     542          <p i18n:msg="" i18n:domain="foo">FooBar</p> 
     543        </html>""") 
     544        translations = DummyTranslations({'Bar': 'Voh'}) 
     545        translations.add_domain('foo', {'FooBar': 'BarFoo'}) 
     546        translator = Translator(translations) 
     547        setup_i18n(tmpl, translator) 
     548        self.assertEqual("""<html> 
     549          <p>BarFoo</p> 
     550        </html>""", tmpl.generate().render()) 
     551         
     552    def test_translate_i18n_domain_without_msg_directives(self): 
     553        #"""translate domain call without i18n:msg directives still uses current domain""" 
     554         
     555        tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/" 
     556            xmlns:i18n="http://genshi.edgewall.org/i18n"> 
     557          <p i18n:msg="">Bar</p> 
     558          <div i18n:domain="foo"> 
     559            <p i18n:msg="">FooBar</p> 
     560            <p i18n:msg="">Bar</p>             
     561            <p>Bar</p> 
     562          </div>           
     563          <p>Bar</p> 
     564        </html>""") 
     565        translations = DummyTranslations({'Bar': 'Voh'}) 
     566        translations.add_domain('foo', {'FooBar': 'BarFoo', 'Bar': 'PT_Foo'}) 
     567        translator = Translator(translations) 
     568        setup_i18n(tmpl, translator) 
     569        self.assertEqual("""<html> 
     570          <p>Voh</p> 
     571          <div> 
     572            <p>BarFoo</p> 
     573            <p>PT_Foo</p> 
     574            <p>PT_Foo</p> 
     575          </div> 
     576          <p>Voh</p> 
     577        </html>""", tmpl.generate().render()) 
     578         
     579    def test_translate_i18n_domain_as_directive_not_attribute(self): 
     580        #"""translate with domain as directive""" 
     581         
     582        tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/" 
     583            xmlns:i18n="http://genshi.edgewall.org/i18n"> 
     584        <i18n:domain name="foo"> 
     585          <p i18n:msg="">FooBar</p> 
     586          <p i18n:msg="">Bar</p> 
     587          <p>Bar</p> 
     588        </i18n:domain> 
     589          <p>Bar</p> 
     590        </html>""") 
     591        translations = DummyTranslations({'Bar': 'Voh'}) 
     592        translations.add_domain('foo', {'FooBar': 'BarFoo', 'Bar': 'PT_Foo'}) 
     593        translator = Translator(translations) 
     594        setup_i18n(tmpl, translator) 
     595        self.assertEqual("""<html> 
     596          <p>BarFoo</p> 
     597          <p>PT_Foo</p> 
     598          <p>PT_Foo</p> 
     599          <p>Voh</p> 
     600        </html>""", tmpl.generate().render()) 
     601         
     602    def test_translate_i18n_domain_nested_directives(self): 
     603        #"""translate with nested i18n:domain directives""" 
     604         
     605        tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/" 
     606            xmlns:i18n="http://genshi.edgewall.org/i18n"> 
     607          <p i18n:msg="">Bar</p> 
     608          <div i18n:domain="foo"> 
     609            <p i18n:msg="">FooBar</p> 
     610            <p i18n:domain="bar" i18n:msg="">Bar</p> 
     611            <p>Bar</p> 
     612          </div>           
     613          <p>Bar</p> 
     614        </html>""") 
     615        translations = DummyTranslations({'Bar': 'Voh'}) 
     616        translations.add_domain('foo', {'FooBar': 'BarFoo', 'Bar': 'foo_Bar'}) 
     617        translations.add_domain('bar', {'Bar': 'bar_Bar'}) 
     618        translator = Translator(translations) 
     619        setup_i18n(tmpl, translator) 
     620        self.assertEqual("""<html> 
     621          <p>Voh</p> 
     622          <div> 
     623            <p>BarFoo</p> 
     624            <p>bar_Bar</p> 
     625            <p>foo_Bar</p> 
     626          </div> 
     627          <p>Voh</p> 
     628        </html>""", tmpl.generate().render()) 
     629         
     630    def test_translate_i18n_domain_with_empty_nested_domain_directive(self): 
     631        #"""translate with empty nested i18n:domain directive does not use dngettext""" 
     632         
     633        tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/" 
     634            xmlns:i18n="http://genshi.edgewall.org/i18n"> 
     635          <p i18n:msg="">Bar</p> 
     636          <div i18n:domain="foo"> 
     637            <p i18n:msg="">FooBar</p> 
     638            <p i18n:domain="" i18n:msg="">Bar</p> 
     639            <p>Bar</p> 
     640          </div>           
     641          <p>Bar</p> 
     642        </html>""") 
     643        translations = DummyTranslations({'Bar': 'Voh'}) 
     644        translations.add_domain('foo', {'FooBar': 'BarFoo', 'Bar': 'foo_Bar'}) 
     645        translations.add_domain('bar', {'Bar': 'bar_Bar'}) 
     646        translator = Translator(translations) 
     647        setup_i18n(tmpl, translator) 
     648        self.assertEqual("""<html> 
     649          <p>Voh</p> 
     650          <div> 
     651            <p>BarFoo</p> 
     652            <p>Voh</p> 
     653            <p>foo_Bar</p> 
     654          </div> 
     655          <p>Voh</p> 
     656        </html>""", tmpl.generate().render()) 
     657 
     658    def test_translate_i18n_choose_as_attribute(self): 
     659        tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/" 
     660            xmlns:i18n="http://genshi.edgewall.org/i18n"> 
     661          <div i18n:choose="one"> 
     662            <p i18n:singular="">FooBar</p> 
     663            <p i18n:plural="">FooBars</p> 
     664          </div> 
     665          <div i18n:choose="two"> 
     666            <p i18n:singular="">FooBar</p> 
     667            <p i18n:plural="">FooBars</p> 
     668          </div> 
     669        </html>""") 
     670        translations = DummyTranslations() 
     671        translator = Translator(translations) 
     672        setup_i18n(tmpl, translator) 
     673        self.assertEqual("""<html> 
     674          <div> 
     675            <p>FooBar</p> 
     676          </div> 
     677          <div> 
     678            <p>FooBars</p> 
     679          </div> 
     680        </html>""", tmpl.generate(one=1, two=2).render()) 
     681         
     682    def test_translate_i18n_choose_as_directive(self): 
     683        tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/" 
     684            xmlns:i18n="http://genshi.edgewall.org/i18n"> 
     685        <i18n:choose numeral="two"> 
     686          <p i18n:singular="">FooBar</p> 
     687          <p i18n:plural="">FooBars</p> 
     688        </i18n:choose> 
     689        <i18n:choose numeral="one"> 
     690          <p i18n:singular="">FooBar</p> 
     691          <p i18n:plural="">FooBars</p> 
     692        </i18n:choose> 
     693        </html>""") 
     694        translations = DummyTranslations() 
     695        translator = Translator(translations) 
     696        setup_i18n(tmpl, translator) 
     697        self.assertEqual("""<html> 
     698          <p>FooBars</p> 
     699          <p>FooBar</p> 
     700        </html>""", tmpl.generate(one=1, two=2).render()) 
     701         
     702    def test_translate_i18n_choose_as_attribute_with_params(self): 
     703        tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/" 
     704            xmlns:i18n="http://genshi.edgewall.org/i18n"> 
     705          <div i18n:choose="two; fname, lname"> 
     706            <p i18n:singular="">Foo $fname $lname</p> 
     707            <p i18n:plural="">Foos $fname $lname</p> 
     708          </div> 
     709        </html>""") 
     710        translations = DummyTranslations({ 
     711            ('Foo %(fname)s %(lname)s', 0): 'Voh %(fname)s %(lname)s', 
     712            ('Foo %(fname)s %(lname)s', 1): 'Vohs %(fname)s %(lname)s', 
     713                 'Foo %(fname)s %(lname)s': 'Voh %(fname)s %(lname)s', 
     714                'Foos %(fname)s %(lname)s': 'Vohs %(fname)s %(lname)s', 
     715        }) 
     716        translator = Translator(translations) 
     717        setup_i18n(tmpl, translator) 
     718        self.assertEqual("""<html> 
     719          <div> 
     720            <p>Vohs John Doe</p> 
     721          </div> 
     722        </html>""", tmpl.generate(two=2, fname='John', lname='Doe').render()) 
     723         
     724    def test_translate_i18n_choose_as_attribute_with_params_and_domain_as_param(self): 
     725        tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/" 
     726            xmlns:i18n="http://genshi.edgewall.org/i18n" 
     727            i18n:domain="foo"> 
     728          <div i18n:choose="two; fname, lname"> 
     729            <p i18n:singular="">Foo $fname $lname</p> 
     730            <p i18n:plural="">Foos $fname $lname</p> 
     731          </div> 
     732        </html>""") 
     733        translations = DummyTranslations() 
     734        translations.add_domain('foo', { 
     735            ('Foo %(fname)s %(lname)s', 0): 'Voh %(fname)s %(lname)s', 
     736            ('Foo %(fname)s %(lname)s', 1): 'Vohs %(fname)s %(lname)s', 
     737                 'Foo %(fname)s %(lname)s': 'Voh %(fname)s %(lname)s', 
     738                'Foos %(fname)s %(lname)s': 'Vohs %(fname)s %(lname)s', 
     739        }) 
     740        translator = Translator(translations) 
     741        setup_i18n(tmpl, translator) 
     742        self.assertEqual("""<html> 
     743          <div> 
     744            <p>Vohs John Doe</p> 
     745          </div> 
     746        </html>""", tmpl.generate(two=2, fname='John', lname='Doe').render()) 
     747         
     748    def test_translate_i18n_choose_as_directive_with_params(self): 
     749        tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/" 
     750            xmlns:i18n="http://genshi.edgewall.org/i18n"> 
     751        <i18n:choose numeral="two" params="fname, lname"> 
     752          <p i18n:singular="">Foo ${fname} ${lname}</p> 
     753          <p i18n:plural="">Foos ${fname} ${lname}</p> 
     754        </i18n:choose> 
     755        <i18n:choose numeral="one" params="fname, lname"> 
     756          <p i18n:singular="">Foo ${fname} ${lname}</p> 
     757          <p i18n:plural="">Foos ${fname} ${lname}</p> 
     758        </i18n:choose> 
     759        </html>""") 
     760        translations = DummyTranslations({ 
     761            ('Foo %(fname)s %(lname)s', 0): 'Voh %(fname)s %(lname)s', 
     762            ('Foo %(fname)s %(lname)s', 1): 'Vohs %(fname)s %(lname)s', 
     763                 'Foo %(fname)s %(lname)s': 'Voh %(fname)s %(lname)s', 
     764                'Foos %(fname)s %(lname)s': 'Vohs %(fname)s %(lname)s', 
     765        }) 
     766        translator = Translator(translations) 
     767        setup_i18n(tmpl, translator) 
     768        self.assertEqual("""<html> 
     769          <p>Vohs John Doe</p> 
     770          <p>Voh John Doe</p> 
     771        </html>""", tmpl.generate(one=1, two=2, 
     772                                  fname='John', lname='Doe').render()) 
     773         
     774    def test_translate_i18n_choose_as_directive_with_params_and_domain_as_directive(self): 
     775        tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/" 
     776            xmlns:i18n="http://genshi.edgewall.org/i18n"> 
     777        <i18n:domain name="foo"> 
     778        <i18n:choose numeral="two" params="fname, lname"> 
     779          <p i18n:singular="">Foo ${fname} ${lname}</p> 
     780          <p i18n:plural="">Foos ${fname} ${lname}</p> 
     781        </i18n:choose> 
     782        </i18n:domain> 
     783        <i18n:choose numeral="one" params="fname, lname"> 
     784          <p i18n:singular="">Foo ${fname} ${lname}</p> 
     785          <p i18n:plural="">Foos ${fname} ${lname}</p> 
     786        </i18n:choose> 
     787        </html>""") 
     788        translations = DummyTranslations() 
     789        translations.add_domain('foo', { 
     790            ('Foo %(fname)s %(lname)s', 0): 'Voh %(fname)s %(lname)s', 
     791            ('Foo %(fname)s %(lname)s', 1): 'Vohs %(fname)s %(lname)s', 
     792                 'Foo %(fname)s %(lname)s': 'Voh %(fname)s %(lname)s', 
     793                'Foos %(fname)s %(lname)s': 'Vohs %(fname)s %(lname)s', 
     794        }) 
     795        translator = Translator(translations) 
     796        setup_i18n(tmpl, translator) 
     797        self.assertEqual("""<html> 
     798          <p>Vohs John Doe</p> 
     799          <p>Foo John Doe</p> 
     800        </html>""", tmpl.generate(one=1, two=2, 
     801                                  fname='John', lname='Doe').render()) 
     802 
     803    def test_extract_i18n_choose_as_attribute(self): 
     804        tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/" 
     805            xmlns:i18n="http://genshi.edgewall.org/i18n"> 
     806          <div i18n:choose="one"> 
     807            <p i18n:singular="">FooBar</p> 
     808            <p i18n:plural="">FooBars</p> 
     809          </div> 
     810          <div i18n:choose="two"> 
     811            <p i18n:singular="">FooBar</p> 
     812            <p i18n:plural="">FooBars</p> 
     813          </div> 
     814        </html>""") 
     815        translator = Translator() 
     816        tmpl.add_directives(Translator.NAMESPACE, translator) 
     817        messages = list(translator.extract(tmpl.stream)) 
     818        self.assertEqual(2, len(messages)) 
     819        self.assertEqual((3, 'ngettext', (u'FooBar', u'FooBars'), []), messages[0]) 
     820        self.assertEqual((7, 'ngettext', (u'FooBar', u'FooBars'), []), messages[1]) 
     821         
     822    def test_extract_i18n_choose_as_directive(self): 
     823        tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/" 
     824            xmlns:i18n="http://genshi.edgewall.org/i18n"> 
     825        <i18n:choose numeral="two"> 
     826          <p i18n:singular="">FooBar</p> 
     827          <p i18n:plural="">FooBars</p> 
     828        </i18n:choose> 
     829        <i18n:choose numeral="one"> 
     830          <p i18n:singular="">FooBar</p> 
     831          <p i18n:plural="">FooBars</p> 
     832        </i18n:choose> 
     833        </html>""") 
     834        translator = Translator() 
     835        tmpl.add_directives(Translator.NAMESPACE, translator) 
     836        messages = list(translator.extract(tmpl.stream)) 
     837        self.assertEqual(2, len(messages)) 
     838        self.assertEqual((3, 'ngettext', (u'FooBar', u'FooBars'), []), messages[0]) 
     839        self.assertEqual((7, 'ngettext', (u'FooBar', u'FooBars'), []), messages[1]) 
     840         
     841    def test_extract_i18n_choose_as_attribute_with_params(self): 
     842        tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/" 
     843            xmlns:i18n="http://genshi.edgewall.org/i18n"> 
     844          <div i18n:choose="two; fname, lname"> 
     845            <p i18n:singular="">Foo $fname $lname</p> 
     846            <p i18n:plural="">Foos $fname $lname</p> 
     847          </div> 
     848        </html>""") 
     849        translator = Translator() 
     850        tmpl.add_directives(Translator.NAMESPACE, translator) 
     851        messages = list(translator.extract(tmpl.stream)) 
     852        self.assertEqual(1, len(messages)) 
     853        self.assertEqual((3, 'ngettext', (u'Foo %(fname)s %(lname)s', 
     854                                          u'Foos %(fname)s %(lname)s'), []), 
     855                         messages[0]) 
     856 
     857    def test_extract_i18n_choose_as_attribute_with_params_and_domain_as_param(self): 
     858        tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/" 
     859            xmlns:i18n="http://genshi.edgewall.org/i18n" 
     860            i18n:domain="foo"> 
     861          <div i18n:choose="two; fname, lname"> 
     862            <p i18n:singular="">Foo $fname $lname</p> 
     863            <p i18n:plural="">Foos $fname $lname</p> 
     864          </div> 
     865        </html>""") 
     866        translator = Translator() 
     867        tmpl.add_directives(Translator.NAMESPACE, translator) 
     868        messages = list(translator.extract(tmpl.stream)) 
     869        self.assertEqual(1, len(messages)) 
     870        self.assertEqual((4, 'ngettext', (u'Foo %(fname)s %(lname)s', 
     871                                          u'Foos %(fname)s %(lname)s'), []), 
     872                         messages[0]) 
     873 
     874    def test_extract_i18n_choose_as_directive_with_params(self): 
     875        tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/" 
     876            xmlns:i18n="http://genshi.edgewall.org/i18n"> 
     877        <i18n:choose numeral="two" params="fname, lname">