diff options
author | matthew <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) |
commit | 6dd43c763e3785bb66997dc7e74d2660b2357f94 (patch) | |
tree | c0a327834caae4b1eb2f4ed85cdab244b3eeef0d /testing | |
parent | 534c5ece4966cef4886ebda59013a1b4daf469aa (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.py | 43 | ||||
-rw-r--r-- | testing/utils.py | 109 |
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 |