source: applications/FeatureProof/trunk/Lib/featureProof/htmlView/testResultsToHTML.py @ 43

Revision 43, 8.8 KB checked in by tal, 6 years ago (diff)
Various things in the test result view can be controlled.
Line 
1import os
2import time
3from fontTools.pens.basePen import BasePen
4from template import tail, testCaseShowRecordsHead, testCaseShowGlyphsHead
5from glyphRecordsToHTML import glyphRecordsToHTML
6try:
7    from cElementTree import fromstring
8except ImportError:
9    from elementtree.ElementTree import fromstring
10
11
12def makeHTML(resultsXML, font, showGlyphs=True, showNotes=True, showPassed=True, glyphPointSize=20):
13    html = []
14
15    canvasCounter = 1
16    engineChangeCounter = 1
17    testCaseCounter = 1
18    pathCache = {}
19    canvasData = []
20
21    tree = fromstring(resultsXML)
22    for element in tree:
23        if element.tag == "statistics":
24            html += _logStatistics(element)
25        elif element.tag == "engineChanges":
26            html += _logEngineChanges(element, engineChangeCounter)
27            engineChangeCounter += 1
28        elif element.tag == "note":
29            if not showNotes:
30                continue
31            html.append("<p class=\"testCaseNote\">%s</p>" % element.get("text"))
32        elif element.tag == "test":
33            html.append("<h2 class=\"withDisclosure\" id=\"testCase%d_head\" onclick=\"toggle('testCase%d');\">Test Case %d</h2>" % (testCaseCounter, testCaseCounter, testCaseCounter))
34            html.append("<div id=\"testCase%d\">" % testCaseCounter)
35            testCaseCounter += 1
36            input = result = expectedResult = None
37            for subElement in element:
38                if subElement.tag == "input":
39                    input = subElement
40                elif subElement.tag == "result":
41                    result = subElement
42                elif subElement.tag == "expectedResult":
43                    expectedResult = subElement
44            if showGlyphs:
45                for subElement in [input, result, expectedResult]:
46                    if subElement is None:
47                        continue
48                    for record in subElement:
49                        name = record.get("name")
50                        if name not in pathCache:
51                            pathCache[name] = _getCanvasGlyphData(name, font)
52                    # input
53                    if subElement.tag == "input":
54                        html.append("<div class=\"testCaseInputCanvasContainer\"><canvas id=\"canvas%d\"></canvas></div>" % canvasCounter)
55                        canvasData.append("[\"canvas%d\", [%s]]," % (canvasCounter, _glyphRecordsToCanvas(subElement)))
56                        canvasCounter += 1
57                    # result
58                    elif subElement.tag == "result":
59                        html.append("<div class=\"testCaseResultCanvasContainer\"><canvas id=\"canvas%d\"></canvas></div>" % canvasCounter)
60                        canvasData.append("[\"canvas%d\", [%s]]," % (canvasCounter, _glyphRecordsToCanvas(subElement)))
61                        canvasCounter += 1
62                    # expected result
63                    elif subElement is not None:
64                        if subElement.get("passed") == "True":
65                            if not showPassed:
66                                continue
67                            c = "testCaseExpectedResultPassedCanvasContainer"
68                        else:
69                            c = "testCaseExpectedResultFailedCanvasContainer"
70                        html.append("<div class=\"%s\"><canvas id=\"canvas%d\"></canvas></div>" % (c, canvasCounter))
71                        canvasData.append("[\"canvas%d\", [%s]]," % (canvasCounter, _glyphRecordsToCanvas(subElement)))
72                        canvasCounter += 1
73            else:
74                showPositions = True
75                if expectedResult:
76                    showPositions = False
77                    for i in expectedResult:
78                        if i.get("xAdvance") != "None" or i.get("yAdvance") != "None"\
79                        or i.get("xPlacement") != "None" or i.get("yPlacement") != "None":
80                            showPositions = True
81                            break
82                html += _logInputAsString(input)
83                html += _logResultAsString(subElement, showPositions)
84                if expectedResult:
85                    html += _logExpectedResultAsString(subElement, showPositions)
86            html.append("</div>")
87    if showGlyphs:
88        head = testCaseShowGlyphsHead
89        head = head.replace("<!-- FONT UPM -->", str(font.info.unitsPerEm))
90        head = head.replace("<!-- FONT DESCENDER -->", str(font.info.descender))
91        head = head.replace("<!-- GLYPH POINT SIZE -->", str(float(glyphPointSize)))
92        glyphData = []
93        for k, v in pathCache.items():
94            glyphData.append("\"%s\" : %s," % (k, v))
95        glyphData = "\n".join(glyphData)
96        head = head.replace("<!-- GLYPH DEFINITIONS -->", glyphData)
97        canvasData = "\n".join(canvasData)
98        head = head.replace("<!-- ALL CANVAS DATA -->", canvasData)
99    else:
100        head = testCaseShowRecordsHead
101    html.insert(0, head)
102    html.append(tail)
103    text = "\n".join(html)
104    return text
105
106def _logStatistics(element):
107    html = []
108    data = {}
109    for subElement in element:
110        data[subElement.tag] = subElement.get("value")
111    for i in ["runTime", "passedTests", "failedTests"]:
112        if i == "runTime":
113            value = "Ran %s tests in %s" % (data["totalTests"], data["runTime"])
114        elif i == "passedTests":
115            value = "%s passed" % data[i]
116        else:
117            value = "%s failed" % data[i]
118        s = "<h1>%s</h1>" % value
119        html.append(s)
120    return html
121
122def _logEngineChanges(element, index):
123    html = ["<h2 class=\"withDisclosure\" id=\"settings%d_head\" onclick=\"toggle('settings%d');\">Settings</h2><div id=\"settings%d\">" % (index, index, index)]
124    for subElement in element:
125        if subElement.tag == "featureStates":
126            for stateGroup in subElement:
127                if stateGroup.tag == "featuresOn":
128                    title = "On"
129                else:
130                    title = "Off"
131                s = "<h3>Features %s:</h3>" % title
132                html.append(s)
133                for i in stateGroup:
134                    s = "<p class=\"testCaseFeature\">%s</p>" % i.get("name")
135                    html.append(s)
136            continue
137        elif subElement.tag == "script":
138            title = "Script"
139            value = subElement.get("value")
140        elif subElement.tag == "language":
141            title = "Language"
142            value = subElement.get("value")
143        elif subElement.tag == "textDirection":
144            title = "Direction"
145            value = subElement.get("value")
146        s = "<h3>%s: <b>%s</b></h3>" % (title, value)
147        html.append(s)
148    html.append("</div>")
149    return html
150
151def _logInputAsString(element):
152    s = "<p class=\"testCaseInput\">%s</p>" % (glyphRecordsToHTML(element, False))
153    return [s]
154
155def _logResultAsString(element, showPositions):
156    s = "<p class=\"testCaseResult\">%s</p>" % (glyphRecordsToHTML(element, showPositions))
157    return [s]
158
159def _logExpectedResultAsString(element, showPositions):
160    if element.get("passed") == "True":
161        c = "testCaseExpectedResultPassed"
162    else:
163        c = "testCaseExpectedResultFailed"
164    s = "<p class=\"%s\">%s</p>" % (c, glyphRecordsToHTML(element, showPositions))
165    return [s]
166
167def _glyphRecordsToCanvas(element):
168    l = []
169    for i in element:
170        name = i.get("name")
171        xP = i.get("xPlacement")
172        if xP == "None":
173            xP = 0
174        else:
175            xP = int(float(xP))
176        xP = int(xP)
177        yP = i.get("yPlacement")
178        if yP == "None":
179            yP = 0
180        else:
181            yP = int(float(yP))
182        xA = i.get("xAdvance")
183        if xA == "None":
184            xA = 0
185        else:
186            xA = int(float(xA))
187        yA = i.get("yAdvance")
188        if yA == "None":
189            yA = 0
190        else:
191            yA = int(float(yA))
192        s = "[\"%s\", %d, %d, %d, %d]" % (name, xP, yP, xA, yA)
193        l.append(s)
194    return ", ".join(l)
195
196
197class CanvasInstructionsPen(BasePen):
198
199    def __init__(self, glyphSet):
200        BasePen.__init__(self, glyphSet)
201        self.instructions = ["['beginPath']"]
202
203    def getInstructions(self):
204        if len(self.instructions) > 1:
205            return self.instructions
206        return []
207
208    def _moveTo(self, (x, y)):
209        self.instructions.append("['moveTo', [%d, %d]]" % (x, y))
210
211    def _lineTo(self, (x, y)):
212        self.instructions.append("['lineTo', [%d, %d]]" % (x, y))
213
214    def _curveToOne(self, (x1, y1), (x2, y2), (x3, y3)):
215        self.instructions.append("['bezierCurveTo', [%d, %d, %d, %d, %d, %d]]" % (x1, y1, x2, y2, x3, y3))
216
217    def _closePath(self):
218        self.instructions.append("['closePath']")
219
220def _getCanvasGlyphData(glyphName, glyphSet):
221    glyph = glyphSet[glyphName]
222    pen = CanvasInstructionsPen(glyphSet)
223    glyph.draw(pen)
224    instructions = pen.getInstructions()
225    instructions.insert(0, str(glyph.width))
226    return "[%s]" % ", ".join(instructions)
227
Note: See TracBrowser for help on using the repository browser.