[Zope-Checkins] CVS: Zope3/lib/python/Zope/TAL/tests - test_htmltalparser.py:1.30 test_talinterpreter.py:1.5
Fred L. Drake, Jr.
fdrake@acm.org
Wed, 12 Jun 2002 11:39:37 -0400
Update of /cvs-repository/Zope3/lib/python/Zope/TAL/tests
In directory cvs.zope.org:/tmp/cvs-serv12767/tests
Modified Files:
test_htmltalparser.py test_talinterpreter.py
Log Message:
Merge from fdrake-tal-i18n-branch:
This is the bulk of the changes from the branch.
=== Zope3/lib/python/Zope/TAL/tests/test_htmltalparser.py 1.29 => 1.30 ===
def check_define_macro(self):
macro = self.initial_program + [
- ('startTag', ('p', [('metal:define-macro', 'M', 2)])),
+ ('startTag', ('p', [('metal:define-macro', 'M', 'metal')])),
rawtext('booh</p>'),
]
program = [
@@ -182,17 +182,17 @@
('setPosition', (1, 0)),
('useMacro',
('M', '$M$', {},
- [('startTag', ('p', [('metal:use-macro', 'M', 2)])),
+ [('startTag', ('p', [('metal:use-macro', 'M', 'metal')])),
rawtext('booh</p>')])),
])
def check_define_slot(self):
macro = self.initial_program + [
- ('startTag', ('p', [('metal:define-macro', 'M', 2)])),
+ ('startTag', ('p', [('metal:define-macro', 'M', 'metal')])),
rawtext('foo'),
('setPosition', (1, 29)),
('defineSlot', ('S',
- [('startTag', ('span', [('metal:define-slot', 'S', 2)])),
+ [('startTag', ('span', [('metal:define-slot', 'S', 'metal')])),
rawtext('spam</span>')])),
rawtext('bar</p>'),
]
@@ -210,13 +210,13 @@
('useMacro',
('M', '$M$',
{'S': [('startTag', ('span',
- [('metal:fill-slot', 'S', 2)])),
+ [('metal:fill-slot', 'S', 'metal')])),
rawtext('spam</span>')]},
- [('startTag', ('p', [('metal:use-macro', 'M', 2)])),
+ [('startTag', ('p', [('metal:use-macro', 'M', 'metal')])),
rawtext('foo'),
('setPosition', (1, 26)),
('fillSlot', ('S',
- [('startTag', ('span', [('metal:fill-slot', 'S', 2)])),
+ [('startTag', ('span', [('metal:fill-slot', 'S', 'metal')])),
rawtext('spam</span>')])),
rawtext('bar</p>')])),
])
@@ -232,7 +232,7 @@
('setPosition', (1, 0)),
('beginScope', {'tal:define': 'xyzzy string:spam'}),
('setLocal', ('xyzzy', '$string:spam$')),
- ('startTag', ('p', [('tal:define', 'xyzzy string:spam', 3)])),
+ ('startTag', ('p', [('tal:define', 'xyzzy string:spam', 'tal')])),
('endScope', ()),
rawtext('</p>'),
])
@@ -243,7 +243,7 @@
('beginScope', {'tal:define': 'local xyzzy string:spam'}),
('setLocal', ('xyzzy', '$string:spam$')),
('startTag', ('p',
- [('tal:define', 'local xyzzy string:spam', 3)])),
+ [('tal:define', 'local xyzzy string:spam', 'tal')])),
('endScope', ()),
rawtext('</p>'),
])
@@ -254,7 +254,7 @@
('beginScope', {'tal:define': 'global xyzzy string:spam'}),
('setGlobal', ('xyzzy', '$string:spam$')),
('startTag', ('p',
- [('tal:define', 'global xyzzy string:spam', 3)])),
+ [('tal:define', 'global xyzzy string:spam', 'tal')])),
('endScope', ()),
rawtext('</p>'),
])
@@ -265,7 +265,7 @@
('beginScope', {'tal:define': 'x string:spam; y x'}),
('setLocal', ('x', '$string:spam$')),
('setLocal', ('y', '$x$')),
- ('startTag', ('p', [('tal:define', 'x string:spam; y x', 3)])),
+ ('startTag', ('p', [('tal:define', 'x string:spam; y x', 'tal')])),
('endScope', ()),
rawtext('</p>'),
])
@@ -276,7 +276,7 @@
('beginScope', {'tal:define': 'x string:;;;;; y x'}),
('setLocal', ('x', '$string:;;$')),
('setLocal', ('y', '$x$')),
- ('startTag', ('p', [('tal:define', 'x string:;;;;; y x', 3)])),
+ ('startTag', ('p', [('tal:define', 'x string:;;;;; y x', 'tal')])),
('endScope', ()),
rawtext('</p>'),
])
@@ -291,7 +291,7 @@
('setGlobal', ('y', '$x$')),
('setLocal', ('z', '$y$')),
('startTag', ('p',
- [('tal:define', 'x string:spam; global y x; local z y', 3)])),
+ [('tal:define', 'x string:spam; global y x; local z y', 'tal')])),
('endScope', ()),
rawtext('</p>'),
])
@@ -303,7 +303,7 @@
('setPosition', (1, 3)),
('beginScope', {'tal:condition': 'python:1'}),
('condition', ('$python:1$',
- [('startTag', ('span', [('tal:condition', 'python:1', 3)])),
+ [('startTag', ('span', [('tal:condition', 'python:1', 'tal')])),
rawtext('<b>foo</b></span>')])),
('endScope', ()),
rawtext('</p>'),
@@ -312,8 +312,8 @@
def check_content_1(self):
self._run_check("<p tal:content='string:foo'>bar</p>", [
('setPosition', (1, 0)),
- ('beginScope', {'tal:content': 'string:foo'}),
- ('startTag', ('p', [('tal:content', 'string:foo', 3)])),
+ ('beginScope', {'tal:content': 'string:foo'}),
+ ('startTag', ('p', [('tal:content', 'string:foo', 'tal')])),
('insertText', ('$string:foo$', [rawtext('bar')])),
('endScope', ()),
rawtext('</p>'),
@@ -323,7 +323,7 @@
self._run_check("<p tal:content='text string:foo'>bar</p>", [
('setPosition', (1, 0)),
('beginScope', {'tal:content': 'text string:foo'}),
- ('startTag', ('p', [('tal:content', 'text string:foo', 3)])),
+ ('startTag', ('p', [('tal:content', 'text string:foo', 'tal')])),
('insertText', ('$string:foo$', [rawtext('bar')])),
('endScope', ()),
rawtext('</p>'),
@@ -334,7 +334,7 @@
('setPosition', (1, 0)),
('beginScope', {'tal:content': 'structure string:<br>'}),
('startTag', ('p',
- [('tal:content', 'structure string:<br>', 3)])),
+ [('tal:content', 'structure string:<br>', 'tal')])),
('insertStructure',
('$string:<br>$', {}, [rawtext('bar')])),
('endScope', ()),
@@ -346,7 +346,7 @@
('setPosition', (1, 0)),
('beginScope', {'tal:replace': 'string:foo'}),
('insertText', ('$string:foo$',
- [('startTag', ('p', [('tal:replace', 'string:foo', 3)])),
+ [('startTag', ('p', [('tal:replace', 'string:foo', 'tal')])),
rawtext('bar</p>')])),
('endScope', ()),
])
@@ -357,7 +357,7 @@
('beginScope', {'tal:replace': 'text string:foo'}),
('insertText', ('$string:foo$',
[('startTag', ('p',
- [('tal:replace', 'text string:foo', 3)])),
+ [('tal:replace', 'text string:foo', 'tal')])),
rawtext('bar</p>')])),
('endScope', ()),
])
@@ -368,7 +368,7 @@
('beginScope', {'tal:replace': 'structure string:<br>'}),
('insertStructure', ('$string:<br>$', {},
[('startTag', ('p',
- [('tal:replace', 'structure string:<br>', 3)])),
+ [('tal:replace', 'structure string:<br>', 'tal')])),
rawtext('bar</p>')])),
('endScope', ()),
])
@@ -380,11 +380,11 @@
('beginScope', {'tal:repeat': 'x python:(1,2,3)'}),
('loop', ('x', '$python:(1,2,3)$',
[('startTag', ('p',
- [('tal:repeat', 'x python:(1,2,3)', 3)])),
+ [('tal:repeat', 'x python:(1,2,3)', 'tal')])),
('setPosition', (1, 33)),
('beginScope', {'tal:replace': 'x'}),
('insertText', ('$x$',
- [('startTag', ('span', [('tal:replace', 'x', 3)])),
+ [('startTag', ('span', [('tal:replace', 'x', 'tal')])),
rawtext('dummy</span>')])),
('endScope', ()),
rawtext('</p>')])),
@@ -400,11 +400,11 @@
{'tal:attributes': 'href string:http://www.zope.org; x string:y',
'name': 'bar', 'href': 'foo'}),
('startTag', ('a',
- [('href', 'foo', 0, '$string:http://www.zope.org$'),
+ [('href', 'foo', 'replace', '$string:http://www.zope.org$', 0),
('name', 'name="bar"'),
('tal:attributes',
- 'href string:http://www.zope.org; x string:y', 3),
- ('x', None, 1, '$string:y$')])),
+ 'href string:http://www.zope.org; x string:y', 'tal'),
+ ('x', None, 'insert', '$string:y$', 0)])),
('endScope', ()),
rawtext('link</a>'),
])
@@ -416,12 +416,14 @@
('beginScope',
{'tal:attributes': 'src string:foo.png',
'tal:replace': 'structure string:<img>'}),
- ('insertStructure', ('$string:<img>$',
- {'src': '$string:foo.png$'},
- [('startTag', ('p',
- [('tal:replace', 'structure string:<img>', 3),
- ('tal:attributes', 'src string:foo.png', 3)])),
- rawtext('duh</p>')])),
+ ('insertStructure',
+ ('$string:<img>$',
+ {'src': ('$string:foo.png$', 0)},
+ [('startTag', ('p',
+ [('tal:replace', 'structure string:<img>', 'tal'),
+ ('tal:attributes', 'src string:foo.png',
+ 'tal')])),
+ rawtext('duh</p>')])),
('endScope', ()),
])
@@ -433,13 +435,13 @@
{'tal:content': 'notHere', 'tal:on-error': 'string:error'}),
('onError',
([('startTag', ('p',
- [('tal:on-error', 'string:error', 3),
- ('tal:content', 'notHere', 3)])),
+ [('tal:on-error', 'string:error', 'tal'),
+ ('tal:content', 'notHere', 'tal')])),
('insertText', ('$notHere$', [rawtext('okay')])),
rawtext('</p>')],
[('startTag', ('p',
- [('tal:on-error', 'string:error', 3),
- ('tal:content', 'notHere', 3)])),
+ [('tal:on-error', 'string:error', 'tal'),
+ ('tal:content', 'notHere', 'tal')])),
('insertText', ('$string:error$', [])),
rawtext('</p>')])),
('endScope', ()),
@@ -454,12 +456,12 @@
('onError',
([('insertText', ('$notHere$',
[('startTag', ('p',
- [('tal:on-error', 'string:error', 3),
- ('tal:replace', 'notHere', 3)])),
+ [('tal:on-error', 'string:error', 'tal'),
+ ('tal:replace', 'notHere', 'tal')])),
rawtext('okay</p>')]))],
[('startTag', ('p',
- [('tal:on-error', 'string:error', 3),
- ('tal:replace', 'notHere', 3)])),
+ [('tal:on-error', 'string:error', 'tal'),
+ ('tal:replace', 'notHere', 'tal')])),
('insertText', ('$string:error$', [])),
rawtext('</p>')])),
('endScope', ()),
@@ -484,7 +486,225 @@
2*"<p metal:fill-slot='y' />" + "</html>", exc)
self._should_error("<p metal:foobar='x' />", exc)
self._should_error("<p metal:define-macro='x'>", exc)
-
+
+ #
+ # I18N test cases
+ #
+
+ def check_i18n_attributes(self):
+ self._run_check("<img alt='foo' i18n:attributes='alt'>", [
+ ('setPosition', (1, 0)),
+ ('beginScope', {'alt': 'foo', 'i18n:attributes': 'alt'}),
+ ('startTag', ('img',
+ [('alt', 'foo', 'replace', None, 1),
+ ('i18n:attributes', 'alt', 'i18n')])),
+ ('endScope', ()),
+ ])
+
+ def check_i18n_translate(self):
+ self._run_check('''\
+<span i18n:translate="">Replace this</span>
+<span i18n:translate="msgid">This is a
+translated string</span>
+<span i18n:translate="">And another
+translated string</span>
+''', [
+ ('setPosition', (1, 0)),
+ ('beginScope', {'i18n:translate': ''}),
+ ('startTag', ('span', [('i18n:translate', '', 'i18n')])),
+ ('insertTranslation', ('', [('rawtextOffset', ('Replace this', 12))])),
+ ('rawtextBeginScope',
+ ('</span>\n', 0, (2, 0), 1, {'i18n:translate': 'msgid'})),
+ ('startTag', ('span', [('i18n:translate', 'msgid', 'i18n')])),
+ ('insertTranslation',
+ ('msgid', [('rawtextColumn', ('This is a\ntranslated string', 17))])),
+ ('rawtextBeginScope', ('</span>\n', 0, (4, 0), 1, {'i18n:translate': ''})),
+ ('startTag', ('span', [('i18n:translate', '', 'i18n')])),
+ ('insertTranslation',
+ ('', [('rawtextColumn', ('And another\ntranslated string', 17))])),
+ ('endScope', ()),
+ ('rawtextColumn', ('</span>\n', 0))])
+
+ def check_i18n_translate_with_nested_tal(self):
+ self._run_check('''\
+<span i18n:translate="">replaceable <p tal:replace="str:here">content</p></span>
+''', [
+ ('setPosition', (1, 0)),
+ ('beginScope', {'i18n:translate': ''}),
+ ('startTag', ('span', [('i18n:translate', '', 'i18n')])),
+ ('insertTranslation',
+ ('',
+ [('rawtextOffset', ('replaceable ', 12)),
+ ('setPosition', (1, 36)),
+ ('beginScope', {'tal:replace': 'str:here'}),
+ ('insertText',
+ ('$str:here$',
+ [('startTag', ('p', [('tal:replace', 'str:here', 'tal')])),
+ ('rawtextOffset', ('content</p>', 11))])),
+ ('endScope', ())])),
+ ('endScope', ()),
+ ('rawtextColumn', ('</span>\n', 0))
+ ])
+
+ def check_i18n_name(self):
+ self._run_check('''\
+<span i18n:translate="">
+ <span tal:replace="str:Lomax" i18n:name="name" /> was born in
+ <span tal:replace="str:Antarctica" i18n:name="country" />.
+</span>
+''', [
+ ('setPosition', (1, 0)),
+ ('beginScope', {'i18n:translate': ''}),
+ ('startTag', ('span', [('i18n:translate', '', 'i18n')])),
+ ('insertTranslation',
+ ('',
+ [('rawtextBeginScope',
+ ('\n ',
+ 2,
+ (2, 2),
+ 0,
+ {'i18n:name': 'name', 'tal:replace': 'str:Lomax'})),
+ ('i18nVariable',
+ ('name',
+ '$str:Lomax$',
+ [('startEndTag',
+ ('span',
+ [('tal:replace', 'str:Lomax', 'tal'),
+ ('i18n:name', 'name', 'i18n')]))])),
+ ('rawtextBeginScope',
+ (' was born in\n ',
+ 2,
+ (3, 2),
+ 1,
+ {'i18n:name': 'country', 'tal:replace': 'str:Antarctica'})),
+ ('i18nVariable',
+ ('country',
+ '$str:Antarctica$',
+ [('startEndTag',
+ ('span',
+ [('tal:replace', 'str:Antarctica', 'tal'),
+ ('i18n:name', 'country', 'i18n')]))])),
+ ('endScope', ()),
+ ('rawtextColumn', ('.\n', 0))])),
+ ('endScope', ()),
+ ('rawtextColumn', ('</span>\n', 0))
+ ])
+
+ def check_i18n_name_implicit_value(self):
+ self._run_check('''\
+<span i18n:translate="">
+ <span i18n:name="name"><b>Jim</b></span> was born in
+ <span i18n:name="country">the USA</span>.
+</span>
+''', [
+ ('setPosition', (1, 0)),
+ ('beginScope', {'i18n:translate': ''}),
+ ('startTag', ('span', [('i18n:translate', '', 'i18n')])),
+ ('insertTranslation',
+ ('',
+ [('rawtextBeginScope', ('\n ', 2, (2, 2), 0, {'i18n:name': 'name'})),
+ ('i18nVariable',
+ ('name',
+ [('rawtextOffset', ('<b>Jim</b>', 10))],
+ [('startTag', ('span', [('i18n:name', 'name', 'i18n')])),
+ ('rawtextOffset', ('<b>Jim</b></span>', 17))])),
+ ('rawtextBeginScope',
+ (' was born in\n ', 2, (3, 2), 1, {'i18n:name': 'country'})),
+ ('i18nVariable',
+ ('country',
+ [('rawtextOffset', ('the USA', 7))],
+ [('startTag', ('span', [('i18n:name', 'country', 'i18n')])),
+ ('rawtextOffset', ('the USA</span>', 14))])),
+ ('endScope', ()),
+ ('rawtextColumn', ('.\n', 0))])),
+ ('endScope', ()),
+ ('rawtextColumn', ('</span>\n', 0))
+ ])
+
+ def check_i18n_context_domain(self):
+ self._run_check("<span i18n:domain='mydomain'/>", [
+ ('setPosition', (1, 0)),
+ ('beginI18nContext', {'domain': 'mydomain'}),
+ ('beginScope', {'i18n:domain': 'mydomain'}),
+ ('startEndTag', ('span', [('i18n:domain', 'mydomain', 'i18n')])),
+ ('endScope', ()),
+ ('endI18nContext', ()),
+ ])
+
+ def check_i18n_context_source(self):
+ self._run_check("<span i18n:source='en'/>", [
+ ('setPosition', (1, 0)),
+ ('beginI18nContext', {'source': 'en'}),
+ ('beginScope', {'i18n:source': 'en'}),
+ ('startEndTag', ('span', [('i18n:source', 'en', 'i18n')])),
+ ('endScope', ()),
+ ('endI18nContext', ()),
+ ])
+
+ def check_i18n_context_source_target(self):
+ self._run_check("<span i18n:source='en' i18n:target='ru'/>", [
+ ('setPosition', (1, 0)),
+ ('beginI18nContext', {'source': 'en', 'target': 'ru'}),
+ ('beginScope', {'i18n:source': 'en', 'i18n:target': 'ru'}),
+ ('startEndTag', ('span', [('i18n:source', 'en', 'i18n'),
+ ('i18n:target', 'ru', 'i18n')])),
+ ('endScope', ()),
+ ('endI18nContext', ()),
+ ])
+
+ def check_i18n_data(self):
+ self._run_check('''\
+<span i18n:data="here/currentTime"
+ i18n:translate="timefmt">2:32 pm</span>
+''', [
+ ('setPosition', (1, 0)),
+ ('beginScope',
+ {'i18n:translate': 'timefmt', 'i18n:data': 'here/currentTime'}),
+ ('startTag',
+ ('span',
+ [('i18n:data', 'here/currentTime', 'i18n'),
+ ('i18n:translate', 'timefmt', 'i18n')])),
+ ('insertTranslation',
+ ('timefmt', [('rawtextOffset', ('2:32 pm', 7))], '$here/currentTime$')),
+ ('endScope', ()),
+ ('rawtextColumn', ('</span>\n', 0))
+ ])
+
+ def check_i18n_data_with_name(self):
+ self._run_check('''\
+At the tone the time will be
+<span i18n:data="here/currentTime"
+ i18n:translate="timefmt"
+ i18n:name="time">2:32 pm</span>... beep!
+''', [
+ ('rawtextBeginScope',
+ ('At the tone the time will be\n',
+ 0,
+ (2, 0),
+ 0,
+ {'i18n:data': 'here/currentTime',
+ 'i18n:name': 'time',
+ 'i18n:translate': 'timefmt'})),
+ ('i18nVariable',
+ ('time',
+ [('insertTranslation',
+ ('timefmt',
+ [('rawtextOffset', ('2:32 pm', 7))],
+ '$here/currentTime$'))],
+ [('startTag',
+ ('span',
+ [('i18n:data', 'here/currentTime', 'i18n'),
+ ('i18n:translate', 'timefmt', 'i18n'),
+ ('i18n:name', 'time', 'i18n')])),
+ ('insertTranslation',
+ ('timefmt',
+ [('rawtextOffset', ('2:32 pm', 7))],
+ '$here/currentTime$')),
+ ('rawtextOffset', ('</span>', 7))])),
+ ('endScope', ()),
+ ('rawtextColumn', ('... beep!\n', 0))
+ ])
+
def test_suite():
suite = unittest.TestSuite()
=== Zope3/lib/python/Zope/TAL/tests/test_talinterpreter.py 1.4 => 1.5 ===
from StringIO import StringIO
-from Zope.TAL.TALDefs import METALError
+from Zope.TAL.TALDefs import METALError, I18NError
from Zope.TAL.HTMLTALParser import HTMLTALParser
from Zope.TAL.TALInterpreter import TALInterpreter
from Zope.TAL.DummyEngine import DummyEngine
@@ -60,6 +60,29 @@
self.macro[0] = ("version", "duh")
+class I18NErrorsTestCase(TestCaseBase):
+
+ def _check(self, src, msg):
+ try:
+ self._compile(src)
+ except I18NError:
+ pass
+ else:
+ self.fail(msg)
+
+ def check_id_with_replace(self):
+ self._check('<p i18n:id="foo" tal:replace="string:splat"></p>',
+ "expected i18n:id with tal:replace to be denied")
+
+ def check_missing_values(self):
+ self._check('<p i18n:attributes=""></p>',
+ "missing i18n:attributes value not caught")
+ self._check('<p i18n:data=""></p>',
+ "missing i18n:data value not caught")
+ self._check('<p i18n:id=""></p>',
+ "missing i18n:id value not caught")
+
+
class OutputPresentationTestCase(TestCaseBase):
def check_attribute_wrapping(self):
@@ -84,6 +107,7 @@
def test_suite():
suite = unittest.TestSuite()
+ suite.addTest(unittest.makeSuite(I18NErrorsTestCase, "check_"))
suite.addTest(unittest.makeSuite(MacroErrorsTestCase, "check_"))
suite.addTest(unittest.makeSuite(OutputPresentationTestCase, "check_"))
return suite