#!/usr/bin/env python
'''
$Id: test_xmltestsuite.py 1938 2003-04-13 16:04:04Z rgbecker $
Test parsing and validation against James Clark's test cases,
as downloaded from httpwww.jclark.comxml import
The .zip file should be in the same directory as this script.
Note that the .zip file can be freely distributed in unmodified form
so it could be added to the pyRXP distribution.
'''
__rcs_id__ = '$Id: test_xmltestsuite.py 1938 2003-04-13 16:04:04Z rgbecker $'
__version__ = '$Revision: 1938 $'[11:-2]
__author__ = 'Stuart Bishop <stuart@stuartbishop.net>'
import unittest, zipfile, sys, os, os.path, codecs
debug = int(os.environ.get('RL_DEBUG','0'))
# Debug is to help me trace down memory bugs
if debug: import time
# 2.2 compatibility - sort of
try:
__file__
except NameError:
__file__ = os.path.join(os.getcwd(),'oops')
class test_pyRXPU(unittest.TestCase):
mod = None
def parse(self,filename,**kw):
if debug: print >> sys.stderr,'About to parse %s' % filename
kw = kw.copy()
kw['ReturnComments'] = 0
kw['ExpandEmpty'] = 1
kw['XMLLessThan'] = 1
kw['ReturnProcessingInstructions'] = 1
kw['ReturnList'] = 1
parser = self.mod.Parser(**kw)
# Change directory in case we are loading entities from cwd
retdir = os.getcwd()
d,n = os.path.split(filename)
os.chdir(d)
try:
f = open(n)
xml = f.read()
return parser.parse(xml)
finally:
try:
f.close()
except:
pass
os.chdir(retdir)
if debug: print >> sys.stderr,'Done parsing %s' % filename
if debug: print >> sys.stderr,'='*60
if debug==1: time.sleep(1)
def getcanonical(self,filename):
''' Parse in the named file, and return it as canonical XML '''
return self._getcan(self.parse(filename))
def _getcan(self,node):
if type(node) is type([]): return ''.join(map(self._getcan, node))
if type(node) in (type(''),type(u'')):
return self._quote(node)
tag,attrs,kids,junk = node
if tag == self.mod.commentTagName:
return u'<!--%s-->' % (kids[0])
elif tag == self.mod.piTagName:
return u'<?%s %s?>' % (attrs['name'],kids[0])
if attrs is None:
attrs = ''
else:
keys = attrs.keys()
keys.sort() # Attributes in lexical order
attrs = ' '.join(
['%s="%s"' % (k,self._quote(attrs[k])) for k in keys]
)
if attrs:
attrs = ' ' + attrs
text = ''.join([self._getcan(kid) for kid in kids])
return '<%s%s>%s</%s>' % (tag,attrs,text,tag)
def _quote(self,txt):
txt = txt.replace('&','&')
txt = txt.replace('<','<')
txt = txt.replace('>','>')
txt = txt.replace('"','"')
txt = txt.replace('\x09','	')
txt = txt.replace('\x0a',' ')
txt = txt.replace('\x0d',' ')
return txt
def _test_valid(self,inname,outname):
inxml = self.getcanonical(inname)
f = codecs.open(outname,mode='r',encoding='utf8')
outxml = f.read()
f.close()
self.assertEqual(inxml,outxml)
def _test_invalid_parse(self,inname):
try:
self.parse(inname,Validate=0)
except self.mod.error,x:
self.fail('Failed to parse %r in non-validating mode' % inname)
def _test_invalid_validate(self,inname):
try:
self.parse(inname,Validate=1)
self.fail('Failed to detect validity error in %r' % inname)
except self.mod.error:
pass
def _test_notwf(self,inname):
try:
self.parse(inname,Validate=0)
self.fail(
'Failed to detect that %r was not well formed' % inname
)
except self.mod.error:
pass
def buildup_test(cls=test_pyRXPU,I=[]):
''' Add test methods to the TestCase '''
cls.valid = []
cls.invalid = []
cls.notwf = []
testdir = os.path.dirname(__file__)
try:
zipf = zipfile.ZipFile(os.path.join(testdir,'xmltest.zip'))
except:
print >> sys.stderr, "Can't locate file xmltest.zip\nPerhaps it should be downloaded from\nhttp://www.reportlab.com/ftp/xmltest.zip\nor\nftp://ftp.jclark.com/pub/xml/xmltest.zip\n"
raise
for zipname in zipf.namelist():
# Extract the files if they don't alrady exist
osname = os.path.join(*zipname.split('/')) # For non-unixes
osname = os.path.join(testdir,osname)
dir = os.path.dirname(osname)
if not os.path.isdir(dir):
os.makedirs(dir)
if not os.path.isfile(osname):
f = open(osname,'wb')
f.write(zipf.read(zipname))
f.close()
if I and zipname not in I: continue
# Add input files to our lists
if os.path.splitext(osname)[1] == '.xml' and zipname.find('out') == -1:
if zipname.find('invalid') != -1:
cls.invalid.append(osname)
elif zipname.find('not-wf') != -1:
cls.notwf.append(osname)
elif zipname.find('valid') != -1:
outname = os.path.join(dir,'out',os.path.basename(osname))
cls.valid.append( (osname,outname) )
# Add 'valid' tests
for inname,outname in cls.valid:
num = int(os.path.splitext(os.path.basename(inname))[0])
dir = os.path.split(os.path.split(inname)[0])[1]
mname = 'test_Valid_%s_%03d' % (dir,num)
def doTest(self,inname=inname,outname=outname):
self._test_valid(inname,outname)
setattr(cls,mname,doTest)
# Add 'invalid' tests
for inname in cls.invalid:
num = int(os.path.splitext(os.path.basename(inname))[0])
mname = 'test_InvalidParse_%03d' % (num)
def doTest(self,inname=inname):
self._test_invalid_parse(inname)
setattr(cls,mname,doTest)
mname = 'test_InvalidValidate_%03d' % (num)
def doTest(self,inname=inname):
self._test_invalid_validate(inname)
setattr(cls,mname,doTest)
# Add 'not wellformed' tests
for inname in cls.notwf:
num = int(os.path.splitext(os.path.basename(inname))[0])
dir = os.path.split(os.path.split(inname)[0])[1]
mname = 'test_NotWellFormed_%s_%03d' % (dir,num)
def doTest(self,inname=inname):
self._test_notwf(inname)
setattr(cls,mname,doTest)
import pyRXPU
cls.mod = pyRXPU
if __name__ == '__main__':
I = filter(lambda a: a[:2]=='-I',sys.argv)
map(sys.argv.remove,I)
I = map(lambda x: x[2:],I)
buildup_test(I=I)
unittest.main()
|