[Zope3-checkins] CVS: Zope3/src/zope/tal/tests - __init__.py:1.1.2.1 markbench.py:1.1.2.1 run.py:1.1.2.1 test_files.py:1.1.2.1 test_htmltalparser.py:1.1.2.1 test_sourcepos.py:1.1.2.1 test_talinterpreter.py:1.1.2.1 test_xmlparser.py:1.1.2.1 utils.py:1.1.2.1
Jim Fulton
jim@zope.com
Mon, 23 Dec 2002 14:33:31 -0500
Update of /cvs-repository/Zope3/src/zope/tal/tests
In directory cvs.zope.org:/tmp/cvs-serv19908/zope/tal/tests
Added Files:
Tag: NameGeddon-branch
__init__.py markbench.py run.py test_files.py
test_htmltalparser.py test_sourcepos.py test_talinterpreter.py
test_xmlparser.py utils.py
Log Message:
Initial renaming before debugging
=== Added File Zope3/src/zope/tal/tests/__init__.py ===
#
# This file is necessary to make this directory a package.
=== Added File Zope3/src/zope/tal/tests/markbench.py ===
#! /usr/bin/env python
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
'''Run benchmarks of TAL vs. DTML'''
try:
import warnings
except ImportError:
pass
else:
warnings.filterwarnings("ignore", category=DeprecationWarning)
import os
os.environ['NO_SECURITY'] = 'true'
import sys
import time
from cStringIO import StringIO
#from DocumentTemplate.DT_HTML import HTMLFile
from zope.tal.htmltalparser import HTMLTALParser
from zope.tal.talinterpreter import TALInterpreter
from zope.tal.dummyengine import DummyEngine
def time_apply(f, args, kwargs, count):
r = [None] * count
for i in range(4):
f(*args, **kwargs)
t0 = time.clock()
for i in r:
pass
t1 = time.clock()
for i in r:
f(*args, **kwargs)
t = time.clock() - t1 - (t1 - t0)
return t / count
def time_zpt(fn, count):
from zope.pagetemplate.pagetemplate import PageTemplate
pt = PageTemplate()
pt.write(open(fn).read())
return time_apply(pt.pt_render, (data,), {}, count)
def time_tal(fn, count):
p = HTMLTALParser()
p.parseFile(fn)
program, macros = p.getCode()
engine = DummyEngine(macros)
engine.globals = data
tal = TALInterpreter(program, macros, engine, StringIO(), wrap=0,
tal=1, strictinsert=0)
return time_apply(tal, (), {}, count)
def time_dtml(fn, count):
html = HTMLFile(fn)
return time_apply(html, (), data, count)
def profile_zpt(fn, count, profiler):
from Products.PageTemplates.PageTemplate import PageTemplate
pt = PageTemplate()
pt.write(open(fn).read())
for i in range(4):
pt.pt_render(extra_context=data)
r = [None] * count
for i in r:
profiler.runcall(pt.pt_render, 0, data)
def profile_tal(fn, count, profiler):
p = HTMLTALParser()
p.parseFile(fn)
program, macros = p.getCode()
engine = DummyEngine(macros)
engine.globals = data
tal = TALInterpreter(program, macros, engine, StringIO(), wrap=0,
tal=1, strictinsert=0)
for i in range(4):
tal()
r = [None] * count
for i in r:
profiler.runcall(tal)
tal_fn = 'benchmark/tal%.2d.html'
dtml_fn = 'benchmark/dtml%.2d.html'
def compare(n, count, profiler=None):
t1 = int(time_zpt(tal_fn % n, count) * 1000 + 0.5)
t2 = int(time_tal(tal_fn % n, count) * 1000 + 0.5)
t3 = 'n/a' # int(time_dtml(dtml_fn % n, count) * 1000 + 0.5)
print '%.2d: %10s %10s %10s' % (n, t1, t2, t3)
if profiler:
profile_tal(tal_fn % n, count, profiler)
def main(count, profiler=None):
n = 1
print '##: %10s %10s %10s' % ('ZPT', 'TAL', 'DTML')
while os.path.isfile(tal_fn % n) and os.path.isfile(dtml_fn % n):
compare(n, count, profiler)
n = n + 1
data = {'x':'X', 'r2': range(2), 'r8': range(8), 'r64': range(64)}
for i in range(10):
data['x%s' % i] = 'X%s' % i
if __name__ == "__main__":
filename = "markbench.prof"
profiler = None
if len(sys.argv) > 1 and sys.argv[1] == "-p":
import profile
profiler = profile.Profile()
del sys.argv[1]
if len(sys.argv) > 1:
for arg in sys.argv[1:]:
compare(int(arg), 25, profiler)
else:
main(25, profiler)
if profiler is not None:
profiler.dump_stats(filename)
import pstats
p = pstats.Stats(filename)
p.strip_dirs()
p.sort_stats('time', 'calls')
try:
p.print_stats(20)
except IOError, e:
if e.errno != errno.EPIPE:
raise
=== Added File Zope3/src/zope/tal/tests/run.py ===
#! /usr/bin/env python
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Run all tests."""
import sys
import zope.tal.tests.utils
import unittest
import zope.tal.tests.test_htmltalparser
import zope.tal.tests.test_talinterpreter
import zope.tal.tests.test_files
import zope.tal.tests.test_sourcepos
def test_suite():
suite = unittest.TestSuite()
suite.addTest(test_htmltalparser.test_suite())
if not utils.skipxml:
import test_xmlparser
suite.addTest(test_xmlparser.test_suite())
suite.addTest(test_talinterpreter.test_suite())
suite.addTest(test_files.test_suite())
suite.addTest(test_sourcepos.test_suite())
return suite
def main():
return utils.run_suite(test_suite())
if __name__ == "__main__":
errs = main()
sys.exit(errs and 1 or 0)
=== Added File Zope3/src/zope/tal/tests/test_files.py ===
#! /usr/bin/env python
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Tests that run driver.py over input files comparing to output files."""
import os
import sys
import glob
from Zope.TAL.tests import utils
import unittest
from Zope.TAL import runtest
class FileTestCase(unittest.TestCase):
def __init__(self, file, dir):
self.__file = file
self.__dir = dir
unittest.TestCase.__init__(self)
# For unittest.
def shortDescription(self):
path = os.path.basename(self.__file)
return '%s (%s)' % (path, self.__class__)
def runTest(self):
basename = os.path.basename(self.__file)
#sys.stdout.write(basename + " ")
sys.stdout.flush()
if basename.startswith('test_metal'):
sys.argv = ["", "-Q", "-m", self.__file]
else:
sys.argv = ["", "-Q", self.__file]
pwd = os.getcwd()
try:
try:
os.chdir(self.__dir)
runtest.main()
finally:
os.chdir(pwd)
except SystemExit, what:
if what.code:
self.fail("output for %s didn't match" % self.__file)
try:
script = __file__
except NameError:
script = sys.argv[0]
def test_suite():
suite = unittest.TestSuite()
dir = os.path.dirname(script)
dir = os.path.abspath(dir)
parentdir = os.path.dirname(dir)
prefix = os.path.join(dir, "input", "test*.")
if utils.skipxml:
xmlargs = []
else:
xmlargs = glob.glob(prefix + "xml")
xmlargs.sort()
htmlargs = glob.glob(prefix + "html")
htmlargs.sort()
args = xmlargs + htmlargs
if not args:
sys.stderr.write("Warning: no test input files found!!!\n")
for arg in args:
case = FileTestCase(arg, parentdir)
suite.addTest(case)
return suite
if __name__ == "__main__":
errs = utils.run_suite(test_suite())
sys.exit(errs and 1 or 0)
=== Added File Zope3/src/zope/tal/tests/test_htmltalparser.py === (760/860 lines abridged)
#! /usr/bin/env python
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Tests for the HTMLTALParser code generator."""
import pprint
import sys
from Zope.TAL.tests import utils
import unittest
from Zope.TAL import HTMLTALParser
from zope.tal.taldefs import TAL_VERSION, TALError, METALError
class TestCaseBase(unittest.TestCase):
prologue = ""
epilogue = ""
initial_program = [('version', TAL_VERSION), ('mode', 'html')]
final_program = []
def _merge(self, p1, p2):
if p1 and p2:
op1, args1 = p1[-1]
op2, args2 = p2[0]
if op1.startswith('rawtext') and op2.startswith('rawtext'):
return (p1[:-1]
+ [rawtext(args1[0] + args2[0])]
+ p2[1:])
return p1+p2
def _run_check(self, source, program, macros={}):
parser = HTMLTALParser.HTMLTALParser()
parser.parseString(self.prologue + source + self.epilogue)
got_program, got_macros = parser.getCode()
program = self._merge(self.initial_program, program)
program = self._merge(program, self.final_program)
[-=- -=- -=- 760 lines omitted -=- -=- -=-]
self._run_check('''\
<p i18n:translate="verify">Your contact email address is recorded as
<a href="mailto:user@example.com"
tal:content="request/submitter"
i18n:name="email">user@host.com</a>
</p>
''', [
('setPosition', (1, 0)),
('beginScope', {'i18n:translate': 'verify'}),
('startTag', ('p', [('i18n:translate', 'verify', 'i18n')])),
('insertTranslation',
('verify',
[('rawtextBeginScope',
('Your contact email address is recorded as\n ',
4,
(2, 4),
0,
{'href': 'mailto:user@example.com',
'i18n:name': 'email',
'tal:content': 'request/submitter'})),
('i18nVariable',
('email',
[('startTag',
('a',
[('href', 'href="mailto:user@example.com"'),
('tal:content', 'request/submitter', 'tal'),
('i18n:name', 'email', 'i18n')])),
('insertText',
('$request/submitter$',
[('rawtextOffset', ('user@host.com', 13))])),
('rawtextOffset', ('</a>', 4))],
None)),
('endScope', ()),
('rawtextColumn', ('\n', 0))])),
('endScope', ()),
('rawtextColumn', ('</p>\n', 0))
])
def test_suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(HTMLTALParserTestCases, "check_"))
suite.addTest(unittest.makeSuite(METALGeneratorTestCases, "check_"))
suite.addTest(unittest.makeSuite(TALGeneratorTestCases, "check_"))
return suite
if __name__ == "__main__":
errs = utils.run_suite(test_suite())
sys.exit(errs and 1 or 0)
=== Added File Zope3/src/zope/tal/tests/test_sourcepos.py ===
#! /usr/bin/env python
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Tests for TALInterpreter."""
import sys
import unittest
from StringIO import StringIO
from zope.tal.htmltalparser import HTMLTALParser
from zope.tal.talinterpreter import TALInterpreter
from zope.tal.talgenerator import TALGenerator
from zope.tal.dummyengine import DummyEngine
page1 = '''<html metal:use-macro="main"><body>
<div metal:fill-slot="body">
page1=<span tal:replace="position:" />
</div>
</body></html>'''
main_template = '''<html metal:define-macro="main"><body>
main_template=<span tal:replace="position:" />
<div metal:define-slot="body" />
main_template=<span tal:replace="position:" />
<div metal:use-macro="foot" />
main_template=<span tal:replace="position:" />
</body></html>'''
footer = '''<div metal:define-macro="foot">
footer=<span tal:replace="position:" />
</div>'''
expected = '''<html><body>
main_template=main_template (2,14)
<div>
page1=page1 (3,6)
</div>
main_template=main_template (4,14)
<div>
footer=footer (2,7)
</div>
main_template=main_template (6,14)
</body></html>'''
class Tests(unittest.TestCase):
def parse(self, eng, s, fn):
gen = TALGenerator(expressionCompiler=eng, xml=0, source_file=fn)
parser = HTMLTALParser(gen)
parser.parseString(s)
program, macros = parser.getCode()
return program, macros
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(),
"Got result:\n%s\nExpected:\n%s"
% (stream.getvalue(), expected))
def test_suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(Tests))
return suite
if __name__ == "__main__":
unittest.main()
=== Added File Zope3/src/zope/tal/tests/test_talinterpreter.py ===
#! /usr/bin/env python
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Tests for TALInterpreter."""
import sys
from Zope.TAL.tests import utils
import unittest
from StringIO import StringIO
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
class TestCaseBase(unittest.TestCase):
def _compile(self, source):
parser = HTMLTALParser()
parser.parseString(source)
program, macros = parser.getCode()
return program, macros
class MacroErrorsTestCase(TestCaseBase):
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 tearDown(self):
try:
self.interpreter()
except METALError:
pass
else:
self.fail("Expected METALError")
def check_mode_error(self):
self.macro[1] = ("mode", "duh")
def check_version_error(self):
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):
# To make sure the attribute-wrapping code is invoked, we have to
# include at least one TAL/METAL attribute to avoid having the start
# tag optimized into a rawtext instruction.
INPUT = r"""
<html this='element' has='a' lot='of' attributes=', so' the='output'
needs='to' be='line' wrapped='.' tal:define='foo nothing'>
</html>"""
EXPECTED = r'''
<html this="element" has="a" lot="of"
attributes=", so" the="output" needs="to"
be="line" wrapped=".">
</html>''' "\n"
self.compare(INPUT, EXPECTED)
def check_entities(self):
INPUT = ('<img tal:define="foo nothing" '
'alt="&a;  
 &a - &; �a; <>" />')
EXPECTED = ('<img alt="&a;  
 '
'&a &#45 &; &#0a; <>" />\n')
self.compare(INPUT, EXPECTED)
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)
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
if __name__ == "__main__":
errs = utils.run_suite(test_suite())
sys.exit(errs and 1 or 0)
=== Added File Zope3/src/zope/tal/tests/test_xmlparser.py ===
#! /usr/bin/env python
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Tests for XMLParser.py."""
import sys
from types import ListType
from Zope.TAL.tests import utils
import unittest
from Zope.TAL import XMLParser
class EventCollector(XMLParser.XMLParser):
def __init__(self):
self.events = []
self.append = self.events.append
XMLParser.XMLParser.__init__(self)
self.parser.ordered_attributes = 1
def get_events(self):
# Normalize the list of events so that buffer artefacts don't
# separate runs of contiguous characters.
L = []
prevtype = None
for event in self.events:
type = event[0]
if type == prevtype == "data":
L[-1] = ("data", L[-1][1] + event[1])
else:
L.append(event)
prevtype = type
self.events = L
return L
# structure markup
def StartElementHandler(self, tag, attrs):
self.append(("starttag", tag, attrs))
def EndElementHandler(self, tag):
self.append(("endtag", tag))
# all other markup
def CommentHandler(self, data):
self.append(("comment", data))
def handle_charref(self, data):
self.append(("charref", data))
def CharacterDataHandler(self, data):
self.append(("data", data))
def StartDoctypeDeclHandler(self, rootelem, publicId, systemId, subset):
self.append(("doctype", rootelem, systemId, publicId, subset))
def XmlDeclHandler(self, version, encoding, standalone):
self.append(("decl", version, encoding, standalone))
def ExternalEntityRefHandler(self, data):
self.append(("entityref", data))
def ProcessingInstructionHandler(self, target, data):
self.append(("pi", target, data))
class EventCollectorExtra(EventCollector):
def handle_starttag(self, tag, attrs):
EventCollector.handle_starttag(self, tag, attrs)
self.append(("starttag_text", self.get_starttag_text()))
class SegmentedFile:
def __init__(self, parts):
self.parts = list(parts)
def read(self, bytes):
if self.parts:
s = self.parts.pop(0)
else:
s = ''
return s
class XMLParserTestCase(unittest.TestCase):
def _run_check(self, source, events, collector=EventCollector):
parser = collector()
if isinstance(source, ListType):
parser.parseStream(SegmentedFile(source))
else:
parser.parseString(source)
self.assertEquals(parser.get_events(),events)
def _run_check_extra(self, source, events):
self._run_check(source, events, EventCollectorExtra)
def _parse_error(self, source):
def parse(source=source):
parser = XMLParser.XMLParser()
parser.parseString(source)
self.assertRaises(XMLParser.XMLParseError, parse)
def check_processing_instruction_plus(self):
self._run_check("<?processing instruction?><a/>", [
("pi", "processing", "instruction"),
("starttag", "a", []),
("endtag", "a"),
])
def _check_simple_html(self):
self._run_check("""\
<?xml version='1.0' encoding='iso-8859-1'?>
<!DOCTYPE html PUBLIC 'foo' 'bar'>
<html>&entity; 
<!--comment1a
-></foo><bar><<?pi?></foo<bar
comment1b-->
<img src='Bar' ismap=''/>sample
text
<!--comment2a- -comment2b-->
</html>
""", [
("decl", "1.0", "iso-8859-1", -1),
("doctype", "html", "foo", "bar", 0),
("starttag", "html", []),
# ("entityref", "entity"),
("data", " \n"),
("comment", "comment1a\n-></foo><bar><<?pi?></foo<bar\ncomment1b"),
("data", "\n"),
("starttag", "img", ["src", "Bar", "ismap", ""]),
("endtag", "img"),
("data", "sample\ntext\n"),
("comment", "comment2a- -comment2b"),
("data", "\n"),
("endtag", "html"),
])
def check_bad_nesting(self):
try:
self._run_check("<a><b></a></b>", [
("starttag", "a", []),
("starttag", "b", []),
("endtag", "a"),
("endtag", "b"),
])
except:
e = sys.exc_info()[1]
self.assert_(e.lineno == 1,
"did not receive correct position information")
else:
self.fail("expected parse error: bad nesting")
def check_attr_syntax(self):
output = [
("starttag", "a", ["b", "v", "c", "v"]),
("endtag", "a"),
]
self._run_check("""<a b='v' c="v"/>""", output)
self._run_check("""<a b = 'v' c = "v"/>""", output)
self._run_check("""<a\nb\n=\n'v'\nc\n=\n"v"\n/>""", output)
self._run_check("""<a\tb\t=\t'v'\tc\t=\t"v"\t/>""", output)
def check_attr_values(self):
self._run_check("""<a b='xxx\n\txxx' c="yyy\t\nyyy" d='\txyz\n'/>""",
[("starttag", "a", ["b", "xxx xxx",
"c", "yyy yyy",
"d", " xyz "]),
("endtag", "a"),
])
self._run_check("""<a b='' c="" d=''/>""", [
("starttag", "a", ["b", "", "c", "", "d", ""]),
("endtag", "a"),
])
def check_attr_entity_replacement(self):
self._run_check("""<a b='&><"''/>""", [
("starttag", "a", ["b", "&><\"'"]),
("endtag", "a"),
])
def check_attr_funky_names(self):
self._run_check("""<a a.b='v' c:d='v' e-f='v'/>""", [
("starttag", "a", ["a.b", "v", "c:d", "v", "e-f", "v"]),
("endtag", "a"),
])
def check_starttag_end_boundary(self):
self._run_check("""<a b='<'/>""", [
("starttag", "a", ["b", "<"]),
("endtag", "a"),
])
self._run_check("""<a b='>'/>""", [
("starttag", "a", ["b", ">"]),
("endtag", "a"),
])
def check_buffer_artefacts(self):
output = [("starttag", "a", ["b", "<"]), ("endtag", "a")]
self._run_check(["<a b='<'/>"], output)
self._run_check(["<a ", "b='<'/>"], output)
self._run_check(["<a b", "='<'/>"], output)
self._run_check(["<a b=", "'<'/>"], output)
self._run_check(["<a b='<", "'/>"], output)
self._run_check(["<a b='<'", "/>"], output)
output = [("starttag", "a", ["b", ">"]), ("endtag", "a")]
self._run_check(["<a b='>'/>"], output)
self._run_check(["<a ", "b='>'/>"], output)
self._run_check(["<a b", "='>'/>"], output)
self._run_check(["<a b=", "'>'/>"], output)
self._run_check(["<a b='>", "'/>"], output)
self._run_check(["<a b='>'", "/>"], output)
def check_starttag_junk_chars(self):
self._parse_error("<")
self._parse_error("<>")
self._parse_error("</>")
self._parse_error("</$>")
self._parse_error("</")
self._parse_error("</a")
self._parse_error("</a")
self._parse_error("<a<a>")
self._parse_error("</a<a>")
self._parse_error("<$")
self._parse_error("<$>")
self._parse_error("<!")
self._parse_error("<a $>")
self._parse_error("<a")
self._parse_error("<a foo='bar'")
self._parse_error("<a foo='bar")
self._parse_error("<a foo='>'")
self._parse_error("<a foo='>")
def check_declaration_junk_chars(self):
self._parse_error("<!DOCTYPE foo $ >")
# Support for the Zope regression test framework:
def test_suite(skipxml=utils.skipxml):
suite = unittest.TestSuite()
if not skipxml:
suite.addTest(unittest.makeSuite(XMLParserTestCase, "check_"))
return suite
if __name__ == "__main__":
errs = utils.run_suite(test_suite(skipxml=0))
sys.exit(errs and 1 or 0)
=== Added File Zope3/src/zope/tal/tests/utils.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Helper functions for the test suite."""
import os
import sys
mydir = os.path.abspath(os.path.dirname(__file__))
codedir = os.path.dirname(os.path.dirname(os.path.dirname(mydir)))
if codedir not in sys.path:
sys.path.append(codedir)
import unittest
# Set skipxml to true if an XML parser could not be found.
skipxml = 0
try:
import xml.parsers.expat
except ImportError:
skipxml = 1
def run_suite(suite, outf=None, errf=None):
if outf is None:
outf = sys.stdout
runner = unittest.TextTestRunner(outf)
result = runner.run(suite)
## print "\n\n"
## if result.errors:
## print "Errors (unexpected exceptions):"
## map(print_error, result.errors)
## print
## if result.failures:
## print "Failures (assertion failures):"
## map(print_error, result.failures)
## print
newerrs = len(result.errors) + len(result.failures)
if newerrs:
print "'Errors' indicate exceptions other than AssertionError."
print "'Failures' indicate AssertionError"
if errf is None:
errf = sys.stderr
errf.write("%d errors, %d failures\n"
% (len(result.errors), len(result.failures)))
return newerrs
def print_error(info):
testcase, (type, e, tb) = info