def testSourcePositions(self): """Ensure source file and position are set correctly by TAL""" macros = {} eng = DummyEngine(macros) page1_program, page1_macros = self.parse(eng, page1, 'page1') main_template_program, main_template_macros = self.parse( eng, main_template, 'main_template') footer_program, footer_macros = self.parse(eng, footer, 'footer') macros['main'] = main_template_macros['main'] macros['foot'] = footer_macros['foot'] stream = StringIO() interp = TALInterpreter(page1_program, macros, eng, stream) interp() self.assertEqual(stream.getvalue().strip(), expected.strip(), stream.getvalue())
def setUp(self): self.engine = DummyEngine() self.engine.setLocal('foo', Message('FoOvAlUe', 'default')) self.engine.setLocal('bar', 'BaRvAlUe') self.engine.setLocal('raw', ' \tRaW\n ') self.engine.setLocal('noxlt', Message("don't translate me"))
def __init__(self, macros=None): self.catalog = {} DummyEngine.__init__(self, macros)
class I18NCornerTestCase(TestCaseBase): def setUp(self): self.engine = DummyEngine() self.engine.setLocal('foo', Message('FoOvAlUe', 'default')) self.engine.setLocal('bar', 'BaRvAlUe') self.engine.setLocal('raw', ' \tRaW\n ') self.engine.setLocal('noxlt', Message("don't translate me")) def _check(self, program, expected): result = StringIO() self.interpreter = TALInterpreter(program, {}, self.engine, stream=result) self.interpreter() self.assertEqual(expected, result.getvalue()) def test_simple_messageid_translate(self): # This test is mainly here to make sure our DummyEngine works # correctly. program, macros = self._compile('<span tal:content="foo"/>') self._check(program, '<span>FOOVALUE</span>\n') program, macros = self._compile('<span tal:replace="foo"/>') self._check(program, 'FOOVALUE\n') def test_replace_with_messageid_and_i18nname(self): program, macros = self._compile( '<div i18n:translate="" >' '<span tal:replace="foo" i18n:name="foo_name"/>' '</div>') self._check(program, '<div>FOOVALUE</div>\n') def test_pythonexpr_replace_with_messageid_and_i18nname(self): program, macros = self._compile( '<div i18n:translate="" >' '<span tal:replace="python: foo" i18n:name="foo_name"/>' '</div>') self._check(program, '<div>FOOVALUE</div>\n') def test_structure_replace_with_messageid_and_i18nname(self): program, macros = self._compile( '<div i18n:translate="" >' '<span tal:replace="structure foo" i18n:name="foo_name"' ' i18n:translate=""/>' '</div>') self._check(program, '<div>FOOVALUE</div>\n') def test_complex_replace_with_messageid_and_i18nname(self): program, macros = self._compile( '<div i18n:translate="" >' '<em i18n:name="foo_name" tal:omit-tag="">' '<span tal:replace="foo"/>' '</em>' '</div>') self._check(program, '<div>FOOVALUE</div>\n') def test_content_with_messageid_and_i18nname(self): program, macros = self._compile( '<div i18n:translate="" >' '<span tal:content="foo" i18n:name="foo_name"/>' '</div>') self._check(program, '<div><span>FOOVALUE</span></div>\n') def test_content_with_messageid_and_i18nname_and_i18ntranslate(self): # Let's tell the user this is incredibly silly! self.assertRaises( I18NError, self._compile, '<span i18n:translate="" tal:content="foo" i18n:name="foo_name"/>') def test_content_with_plaintext_and_i18nname_and_i18ntranslate(self): # Let's tell the user this is incredibly silly! self.assertRaises( I18NError, self._compile, '<span i18n:translate="" i18n:name="color_name">green</span>') def test_translate_static_text_as_dynamic(self): 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') def test_translate_static_text_as_dynamic_from_bytecode(self): program = [('version', '1.6'), ('mode', 'html'), ('setPosition', (1, 0)), ('beginScope', { 'i18n:translate': '' }), ('startTag', ('div', [('i18n:translate', '', 'i18n')])), ('insertTranslation', ('', [ ('rawtextOffset', ('This is text for ', 17)), ('setPosition', (1, 40)), ('beginScope', { 'tal:content': 'bar', 'i18n:name': 'bar_name', 'i18n:translate': '' }), ('i18nVariable', ('bar_name', [ ('startTag', ('span', [('i18n:translate', '', 'i18n'), ('tal:content', 'bar', 'tal'), ('i18n:name', 'bar_name', 'i18n')])), ('insertTranslation', ('', [('insertText', ('$bar$', []))])), ('rawtextOffset', ('</span>', 7)) ], None, 0)), ('endScope', ()), ('rawtextOffset', ('.', 1)) ])), ('endScope', ()), ('rawtextOffset', ('</div>', 6))] self._check(program, '<div>THIS IS TEXT FOR <span>BARVALUE</span>.</div>\n') def test_for_correct_msgids(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('BaRvAlUe', msgids[0][0]) 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_for_raw_msgids(self): # Test for Issue 314: i18n:translate removes line breaks from # <pre>...</pre> contents # HTML mode self.engine.translationDomain.clearMsgids() result = StringIO() program, macros = self._compile( '<div i18n:translate=""> This is text\n' ' \tfor\n div. </div>' '<pre i18n:translate=""> This is text\n' ' <b>\tfor</b>\n pre. </pre>') 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\n <b>\tfor</b>\n pre. ', msgids[0][0]) self.assertEqual('This is text for div.', msgids[1][0]) self.assertEqual( '<div>THIS IS TEXT FOR DIV.</div>' '<pre> THIS IS TEXT\n <B>\tFOR</B>\n PRE. </pre>\n', result.getvalue()) # XML mode self.engine.translationDomain.clearMsgids() result = StringIO() parser = TALParser() parser.parseString( '<?xml version="1.0"?>\n' '<pre xmlns:i18n="http://xml.zope.org/namespaces/i18n"' ' i18n:translate=""> This is text\n' ' <b>\tfor</b>\n barvalue. </pre>') program, macros = parser.getCode() self.interpreter = TALInterpreter(program, {}, self.engine, stream=result) self.interpreter() 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]) self.assertEqual( '<?xml version="1.0"?>\n' '<pre>THIS IS TEXT <B> FOR</B> BARVALUE.</pre>\n', result.getvalue()) def test_raw_msgids_and_i18ntranslate_i18nname(self): self.engine.translationDomain.clearMsgids() result = StringIO() program, macros = self._compile( '<div i18n:translate=""> This is text\n \tfor\n' '<pre tal:content="raw" i18n:name="raw"' ' i18n:translate=""></pre>.</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(' \tRaW\n ', msgids[0][0]) self.assertEqual('This is text for ${raw}.', msgids[1][0]) self.assertEqual({'raw': '<pre> \tRAW\n </pre>'}, msgids[1][1]) self.assertEqual( u'<div>THIS IS TEXT FOR <pre> \tRAW\n </pre>.</div>\n', result.getvalue()) def test_for_handling_unicode_vars(self): # Make sure that non-ASCII Unicode is substituted correctly. # http://collector.zope.org/Zope3-dev/264 program, macros = self._compile( "<div i18n:translate='' tal:define='bar python:unichr(0xC0)'>" "Foo <span tal:replace='bar' i18n:name='bar' /></div>") self._check(program, u"<div>FOO \u00C0</div>\n") def test_for_untranslated_messageid_simple(self): program, macros = self._compile('<span tal:content="noxlt"/>') self._check(program, "<span>don't translate me</span>\n") def test_for_untranslated_messageid_i18nname(self): program, macros = self._compile( '<div i18n:translate="" >' '<span tal:replace="python: noxlt" i18n:name="foo_name"/>' '</div>') self._check(program, "<div>don't translate me</div>\n")
def setUp(self): dummy, macros = self._compile('<p metal:define-macro="M">Booh</p>') self.macro = macros['M'] self.engine = DummyEngine(macros) program, dummy = self._compile('<p metal:use-macro="M">Bah</p>') self.interpreter = TALInterpreter(program, {}, self.engine)
def compare(self, INPUT, EXPECTED): program, macros = self._compile(INPUT) sio = StringIO() interp = TALInterpreter(program, {}, DummyEngine(), sio, wrap=60) interp() self.assertEqual(sio.getvalue(), EXPECTED)
class I18NCornerTestCase(TestCaseBase): def setUp(self): self.engine = DummyEngine() self.engine.setLocal('foo', Message('FoOvAlUe', 'default')) self.engine.setLocal('bar', 'BaRvAlUe') self.engine.setLocal('raw', ' \tRaW\n ') self.engine.setLocal('noxlt', Message("don't translate me")) def _check(self, program, expected): result = StringIO() self.interpreter = TALInterpreter(program, {}, self.engine, stream=result) self.interpreter() self.assertEqual(expected, result.getvalue()) def test_simple_messageid_translate(self): # This test is mainly here to make sure our DummyEngine works # correctly. program, macros = self._compile('<span tal:content="foo"/>') self._check(program, '<span>FOOVALUE</span>\n') program, macros = self._compile('<span tal:replace="foo"/>') self._check(program, 'FOOVALUE\n') def test_replace_with_messageid_and_i18nname(self): program, macros = self._compile( '<div i18n:translate="" >' '<span tal:replace="foo" i18n:name="foo_name"/>' '</div>') self._check(program, '<div>FOOVALUE</div>\n') def test_pythonexpr_replace_with_messageid_and_i18nname(self): program, macros = self._compile( '<div i18n:translate="" >' '<span tal:replace="python: foo" i18n:name="foo_name"/>' '</div>') self._check(program, '<div>FOOVALUE</div>\n') def test_structure_replace_with_messageid_and_i18nname(self): program, macros = self._compile( '<div i18n:translate="" >' '<span tal:replace="structure foo" i18n:name="foo_name"/>' '</div>') self._check(program, '<div>FOOVALUE</div>\n') def test_complex_replace_with_messageid_and_i18nname(self): program, macros = self._compile( '<div i18n:translate="" >' '<em i18n:name="foo_name">' '<span tal:replace="foo"/>' '</em>' '</div>') self._check(program, '<div>FOOVALUE</div>\n') def test_content_with_messageid_and_i18nname(self): program, macros = self._compile( '<div i18n:translate="" >' '<span tal:content="foo" i18n:name="foo_name"/>' '</div>') self._check(program, '<div><span>FOOVALUE</span></div>\n') def test_content_with_messageid_and_i18nname_and_i18ntranslate(self): # Let's tell the user this is incredibly silly! self.assertRaises( I18NError, self._compile, '<span i18n:translate="" tal:content="foo" i18n:name="foo_name"/>') def test_content_with_plaintext_and_i18nname_and_i18ntranslate(self): # Let's tell the user this is incredibly silly! self.assertRaises( I18NError, self._compile, '<span i18n:translate="" i18n:name="color_name">green</span>') def test_translate_static_text_as_dynamic(self): 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') def test_translate_static_text_as_dynamic_from_bytecode(self): program = [('version', '1.5'), ('mode', 'html'), ('setPosition', (1, 0)), ('beginScope', {'i18n:translate': ''}), ('startTag', ('div', [('i18n:translate', '', 'i18n')])), ('insertTranslation', ('', [('rawtextOffset', ('This is text for ', 17)), ('setPosition', (1, 40)), ('beginScope', {'tal:content': 'bar', 'i18n:name': 'bar_name', 'i18n:translate': ''}), ('i18nVariable', ('bar_name', [('startTag', ('span', [('i18n:translate', '', 'i18n'), ('tal:content', 'bar', 'tal'), ('i18n:name', 'bar_name', 'i18n')])), ('insertTranslation', ('', [('insertText', ('$bar$', []))])), ('rawtextOffset', ('</span>', 7))], None, 0)), ('endScope', ()), ('rawtextOffset', ('.', 1))])), ('endScope', ()), ('rawtextOffset', ('</div>', 6)) ] self._check(program, '<div>THIS IS TEXT FOR <span>BARVALUE</span>.</div>\n') def _getCollectingTranslationDomain(self): class CollectingTranslationService(DummyTranslationService): data = [] def translate(self, domain, msgid, mapping=None, context=None, target_language=None, default=None): self.data.append((msgid, mapping)) return DummyTranslationService.translate( self, domain, msgid, mapping, context, target_language, default) xlatsvc = CollectingTranslationService() self.engine.translationService = xlatsvc return xlatsvc def test_for_correct_msgids(self): xlatdmn = self._getCollectingTranslationDomain() 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 = list(xlatdmn.data) msgids.sort() self.assertEqual(2, len(msgids)) self.assertEqual('BaRvAlUe', msgids[0][0]) 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_for_raw_msgids(self): # Test for Issue 314: i18n:translate removes line breaks from # <pre>...</pre> contents # HTML mode xlatdmn = self._getCollectingTranslationDomain() result = StringIO() program, macros = self._compile( '<div i18n:translate=""> This is text\n' ' \tfor\n div. </div>' '<pre i18n:translate=""> This is text\n' ' <b>\tfor</b>\n pre. </pre>') self.interpreter = TALInterpreter(program, {}, self.engine, stream=result) self.interpreter() msgids = list(xlatdmn.data) msgids.sort() self.assertEqual(2, len(msgids)) self.assertEqual(' This is text\n <b>\tfor</b>\n pre. ', msgids[0][0]) self.assertEqual('This is text for div.', msgids[1][0]) self.assertEqual( '<div>THIS IS TEXT FOR DIV.</div>' '<pre> THIS IS TEXT\n <B>\tFOR</B>\n PRE. </pre>\n', result.getvalue()) # XML mode xlatdmn = self._getCollectingTranslationDomain() result = StringIO() parser = TALParser() parser.parseString( '<?xml version="1.0"?>\n' '<pre xmlns:i18n="http://xml.zope.org/namespaces/i18n"' ' i18n:translate=""> This is text\n' ' <b>\tfor</b>\n barvalue. </pre>') program, macros = parser.getCode() self.interpreter = TALInterpreter(program, {}, self.engine, stream=result) self.interpreter() msgids = list(xlatdmn.data) msgids.sort() self.assertEqual(1, len(msgids)) self.assertEqual('This is text <b> for</b> barvalue.', msgids[0][0]) self.assertEqual( '<?xml version="1.0"?>\n' '<pre>THIS IS TEXT <B> FOR</B> BARVALUE.</pre>\n', result.getvalue()) def test_raw_msgids_and_i18ntranslate_i18nname(self): xlatdmn = self._getCollectingTranslationDomain() result = StringIO() program, macros = self._compile( '<div i18n:translate=""> This is text\n \tfor\n' '<pre tal:content="raw" i18n:name="raw"' ' i18n:translate=""></pre>.</div>') self.interpreter = TALInterpreter(program, {}, self.engine, stream=result) self.interpreter() msgids = list(xlatdmn.data) msgids.sort() self.assertEqual(2, len(msgids)) self.assertEqual(' \tRaW\n ', msgids[0][0]) self.assertEqual('This is text for ${raw}.', msgids[1][0]) self.assertEqual({'raw': '<pre> \tRAW\n </pre>'}, msgids[1][1]) self.assertEqual( u'<div>THIS IS TEXT FOR <pre> \tRAW\n </pre>.</div>\n', result.getvalue()) def test_for_handling_unicode_vars(self): # Make sure that non-ASCII Unicode is substituted correctly. # http://collector.zope.org/Zope3-dev/264 program, macros = self._compile( "<div i18n:translate='' tal:define='bar python:unichr(0xC0)'>" "Foo <span tal:replace='bar' i18n:name='bar' /></div>") self._check(program, u"<div>FOO \u00C0</div>\n") def test_for_untranslated_messageid_simple(self): program, macros = self._compile('<span tal:content="noxlt"/>') self._check(program, "<span>don't translate me</span>\n") def test_for_untranslated_messageid_i18nname(self): program, macros = self._compile( '<div i18n:translate="" >' '<span tal:replace="python: noxlt" i18n:name="foo_name"/>' '</div>') self._check(program, "<div>don't translate me</div>\n")