Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/testing
diff options
context:
space:
mode:
authormatthew <matthew@38b22f21-9aea-0310-abfc-843a9883df58>2005-07-08 02:05:05 (GMT)
committer matthew <matthew@38b22f21-9aea-0310-abfc-843a9883df58>2005-07-08 02:05:05 (GMT)
commit6dd43c763e3785bb66997dc7e74d2660b2357f94 (patch)
treec0a327834caae4b1eb2f4ed85cdab244b3eeef0d /testing
parent534c5ece4966cef4886ebda59013a1b4daf469aa (diff)
Merging testblock and utils.py from 0.6 branch
git-svn-id: https://exe.svn.sourceforge.net/svnroot/exe/trunk@933 38b22f21-9aea-0310-abfc-843a9883df58
Diffstat (limited to 'testing')
-rw-r--r--testing/testblock.py43
-rw-r--r--testing/utils.py109
2 files changed, 124 insertions, 28 deletions
diff --git a/testing/testblock.py b/testing/testblock.py
index a3dcd7f..ea0cc41 100644
--- a/testing/testblock.py
+++ b/testing/testblock.py
@@ -24,7 +24,8 @@ from exe.webui.blockfactory import g_blockFactory
from exe.webui.renderable import Renderable
from exe.engine.node import Node
from exe.application import Application
-from utils import SuperTestCase, HTMLTidy
+from utils import SuperTestCase, HTMLChecker
+from nevow.context import RequestContext
# ===========================================================================
class TestBlock(SuperTestCase):
@@ -32,12 +33,42 @@ class TestBlock(SuperTestCase):
Tests that blocks can render stuff
"""
- def testBlock(self):
+ # TODO: In trunk, we shouldn't ignore any error messages
+ ignoreErrorMsgs = [
+ 'No declaration for attribute border of element img',
+ 'Element img does not carry attribute alt',
+ 'Element body content does not follow the DTD, expecting (p | h1 | h2 '
+ '| h3 | h4 | h5 | h6 | div | ul | ol | dl | pre | hr | blockquote | '
+ 'address | fieldset | table | form | noscript | ins | del | script)*, '
+ 'got (a a img img select a div )',
+ 'No declaration for attribute align of element img',
+ 'Element script does not carry attribute type',
+ 'No declaration for attribute language of element script',
+ 'Element form content does not follow the DTD, expecting (p | h1 | h2 '
+ '| h3 | h4 | h5 | h6 | div | ul | ol | dl | pre | hr | blockquote | '
+ 'address | fieldset | table | noscript | ins | del | script)*, got '
+ '(input input input div ).',
+ 'No declaration for attribute name of element form',
+ 'No declaration for attribute onload of element form',
+ 'Element table content does not follow the DTD, expecting (caption? , '
+ '(col* | colgroup*) , thead? , tfoot? , (tbody+ | tr+)), got '
+ '(th th th tr )',
+ 'Element form content does not follow the DTD, expecting (p | h1 | h2 '
+ '| h3 | h4 | h5 | h6 | div | ul | ol | dl | pre | hr | blockquote | '
+ 'address | fieldset | table | noscript | ins | del | script)*, got '
+ '(input input input div )',
+ ]
+
+ def testAuthoringPage(self):
"""Creates a block for a freetext idevice
and makes it render"""
# Pretend to add an idevice
request = self._request(action='AddIdevice', object='1')
- self.mainpage.authoringPage.render(request)
+ ctx = RequestContext(request)
+ html = self.mainpage.authoringPage.render(request)
+ tidier = HTMLChecker(html, True, self.ignoreErrorMsgs)
+ if not tidier.check():
+ self.fail('Authoring Page generated bad XHTML')
ln = len(self.package.currentNode.idevices)
assert ln >= 1, 'Should be at least one idevice, only %s' % ln
idevice = self.package.currentNode.idevices[0]
@@ -45,10 +76,10 @@ class TestBlock(SuperTestCase):
assert ln >= 1, 'Should be at least one block, only %s' % ln
block = self.mainpage.authoringPage.blocks[0]
assert block.idevice is idevice
- print dir(self)
html = block.renderEditButtons()
- tidier = HTMLTidy(html)
- tidier.check()
+ tidier = HTMLChecker(html, False, self.ignoreErrorMsgs)
+ if not tidier.check():
+ self.fail('Authoring Page generated bad XHTML')
diff --git a/testing/utils.py b/testing/utils.py
index d7e64d5..c3e0fd7 100644
--- a/testing/utils.py
+++ b/testing/utils.py
@@ -19,8 +19,7 @@
import logging
from logging import DEBUG, INFO, WARNING, ERROR, CRITICAL
-import sys, unittest
-#TODO Popen3 not available on Windows!!! from popen2 import Popen3
+import os, sys, unittest
from exe.application import Application
from exe.engine.config import Config
from exe.engine.configparser import ConfigParser
@@ -131,46 +130,112 @@ class SuperTestCase(unittest.TestCase):
return FakeRequest(**kwargs)
-class HTMLTidy(object):
+class HTMLChecker(object):
"""Use this to check html output with htmltidy.
Only works on *nix
"""
- def __init__(self, html):
+ def __init__(self, html, expectHead, resToIgnore=[]):
"""
'html' is the html/xhtml that you want to check
+ if 'expectHead' is false, we'll wrap html in a nice header so as not to
+ kill pylint
+ 'resToIgnore' a sequence of strings or regular expressions to filter out
+ some errors
+ filter them out of the list of warnings/errors
"""
- self.html = html
+ # Wrap the html in proper document tags if necessary
+ if not expectHead:
+ self.html = '<html><head><title>No Title</title></head><body>%s</body></html>' % html
+ else:
+ self.html = html
+ self.resToIgnore = resToIgnore
def check(self):
"""
Actually runs htmltidy to check the html
"""
+ try:
+ from popen2 import Popen3
+ except ImportError:
+ # Windows doesn't have Popen3
+ print '-> Popen3 not available, skipping test <-'
+ return
htmlFile = open('tmp.html', 'wb')
- #htmlFile.write(self.html)
-
- htmlFile.write('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0'
- 'Strict//EN"'
- '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n'
- '<html><head><title>testing</title></head><body>'
- '<notag>hello</body></html>')
+ htmlFile.write(self.html)
htmlFile.close()
- process = Popen3('tidy tmp.html', True)
+ process = Popen3('xmllint --dtdvalid xhtml1-strict.dtd tmp.html', True)
ret = process.wait()
- print dir(self)
+ if os.WIFEXITED(ret):
+ ret = os.WEXITSTATUS(ret)
+ else:
+ raise ValueError("XMLLint not exited, when should of")
+ err = process.childerr.read()
+ out = process.fromchild.read()
if ret == 0:
- print 'ok'
- elif ret == 256:
- print 'Warnings'
- elif ret == 512:
- print 'Errors'
+ # Perfect!
+ return True
+ elif ret in (1, 3,4):
+ # Here we have errors and must filter some out before returning
+ return self.filterErrors(err, ret)
else:
- print ret
- print process.childerr.read()
+ raise ValueError('Unknown return code returned by xmllint: %d' % ret)
+ def filterErrors(self, stderr, returnCode):
+ """
+ Takes the stderr output of xmllint and filters it against our
+ regularExpressions, prints the result and raises
+ an assertion error if
+ """
+ # Each error consists of one or more lines, the first line can be told
+ # because it starts with "tmp.html:\d+:"
+ stderr = stderr.split('\n')
+ if stderr[-1] == '':
+ # Ignore last two lines of rubbish :)
+ del stderr[-2:]
+ errors = {}
+ for line in stderr:
+ if line.startswith('tmp.html:'):
+ key = line
+ errors[key] = [line]
+ else:
+ errors[key].append(line)
+ # Filter only the first line of each error against the regexps
+ for reg in self.resToIgnore:
+ if hasattr(reg, 'search'):
+ # Regular expression search filter
+ check = lambda k: reg.search(k)
+ else:
+ # String in filter
+ check = lambda k: reg in k
+ for key in errors.keys():
+ if check(key):
+ del errors[key]
+ # Now if there are any left print them out and fail the test
+ if errors:
+ errorFile = open('tmp.html.errors', 'w')
+ def output(line=''):
+ print line
+ errorFile.write(line+'\n')
+ keys = errors.keys()
+ keys.sort()
+ if returnCode == 1:
+ output("Invalid XML:")
+ else:
+ output("Errors in HTML:")
+ for key in keys:
+ error = errors[key]
+ for line in error:
+ output(line)
+ output()
+ output('Run this test on its own and then examing "tmp.html" ')
+ output('for more info. Error output save to "tmp.html.errors"')
+ errorFile.close()
+ return False
+ else:
+ return True
-
class TestSuperTestCase(SuperTestCase):
"""
Just provides a simple test to check that the initialisation code is running