|
| 1 | +from __future__importabsolute_import,division,unicode_literals |
| 2 | + |
| 3 | +importwarnings |
| 4 | +importre |
| 5 | + |
| 6 | +importpytest |
| 7 | + |
| 8 | +from .supportimportTestData,convert,convertExpected,treeTypes |
| 9 | +fromhtml5libimporthtml5parser,constants |
| 10 | + |
| 11 | + |
| 12 | +classTreeConstructionFile(pytest.File): |
| 13 | +defcollect(self): |
| 14 | +tests=TestData(str(self.fspath),"data") |
| 15 | +fori,testinenumerate(tests): |
| 16 | +fortreeName,treeClassinsorted(treeTypes.items()): |
| 17 | +fornamespaceHTMLElementsin (True,False): |
| 18 | +ifnamespaceHTMLElements: |
| 19 | +nodeid="%d::%s::namespaced"% (i,treeName) |
| 20 | +else: |
| 21 | +nodeid="%d::%s::void-namespace"% (i,treeName) |
| 22 | +item=ParserTest(nodeid,self, |
| 23 | +test,treeClass,namespaceHTMLElements) |
| 24 | +item.add_marker(getattr(pytest.mark,treeName)) |
| 25 | +ifnamespaceHTMLElements: |
| 26 | +item.add_marker(pytest.mark.namespaced) |
| 27 | +iftreeClassisNone: |
| 28 | +item.add_marker(pytest.mark.skipif(True,reason="Treebuilder not loaded")) |
| 29 | +yielditem |
| 30 | + |
| 31 | + |
| 32 | +defconvertTreeDump(data): |
| 33 | +return"\n".join(convert(3)(data).split("\n")[1:]) |
| 34 | + |
| 35 | +namespaceExpected=re.compile(r"^(\s*)<(\S+)>",re.M).sub |
| 36 | + |
| 37 | + |
| 38 | +classParserTest(pytest.Item): |
| 39 | +def__init__(self,name,parent,test,treeClass,namespaceHTMLElements): |
| 40 | +super(ParserTest,self).__init__(name,parent) |
| 41 | +self.obj=lambda:1# this is to hack around skipif needing a function! |
| 42 | +self.test=test |
| 43 | +self.treeClass=treeClass |
| 44 | +self.namespaceHTMLElements=namespaceHTMLElements |
| 45 | + |
| 46 | +defruntest(self): |
| 47 | +p=html5parser.HTMLParser(tree=self.treeClass, |
| 48 | +namespaceHTMLElements=self.namespaceHTMLElements) |
| 49 | + |
| 50 | +input=self.test['data'] |
| 51 | +fragmentContainer=self.test['document-fragment'] |
| 52 | +expected=self.test['document'] |
| 53 | +expectedErrors=self.test['errors'].split("\n")ifself.test['errors']else [] |
| 54 | + |
| 55 | +withwarnings.catch_warnings(): |
| 56 | +warnings.simplefilter("error") |
| 57 | +try: |
| 58 | +iffragmentContainer: |
| 59 | +document=p.parseFragment(input,fragmentContainer) |
| 60 | +else: |
| 61 | +document=p.parse(input) |
| 62 | +exceptconstants.DataLossWarning: |
| 63 | +pytest.skip("data loss warning") |
| 64 | + |
| 65 | +output=convertTreeDump(p.tree.testSerializer(document)) |
| 66 | + |
| 67 | +expected=convertExpected(expected) |
| 68 | +ifself.namespaceHTMLElements: |
| 69 | +expected=namespaceExpected(r"\1<html \2>",expected) |
| 70 | + |
| 71 | +errorMsg="\n".join(["\n\nInput:",input,"\nExpected:",expected, |
| 72 | +"\nReceived:",output]) |
| 73 | +assertexpected==output,errorMsg |
| 74 | + |
| 75 | +errStr= [] |
| 76 | +for (line,col),errorcode,datavarsinp.errors: |
| 77 | +assertisinstance(datavars,dict),"%s, %s"% (errorcode,repr(datavars)) |
| 78 | +errStr.append("Line: %i Col: %i %s"% (line,col, |
| 79 | +constants.E[errorcode]%datavars)) |
| 80 | + |
| 81 | +errorMsg2="\n".join(["\n\nInput:",input, |
| 82 | +"\nExpected errors ("+str(len(expectedErrors))+"):\n"+"\n".join(expectedErrors), |
| 83 | +"\nActual errors ("+str(len(p.errors))+"):\n"+"\n".join(errStr)]) |
| 84 | +ifFalse:# we're currently not testing parse errors |
| 85 | +assertlen(p.errors)==len(expectedErrors),errorMsg2 |
| 86 | + |
| 87 | +defrepr_failure(self,excinfo): |
| 88 | +traceback=excinfo.traceback |
| 89 | +ntraceback=traceback.cut(path=__file__) |
| 90 | +excinfo.traceback=ntraceback.filter() |
| 91 | + |
| 92 | +returnexcinfo.getrepr(funcargs=True, |
| 93 | +showlocals=False, |
| 94 | +style="short",tbfilter=False) |