Quellcode durchsuchen

Improve fortune parsing

Hamilton Turner vor 10 Jahren
Ursprung
Commit
5f9c6760ad

+ 38 - 6
toolset/benchmark/fortune_html_parser.py

@@ -6,7 +6,24 @@ from difflib import unified_diff
 class FortuneHTMLParser(HTMLParser):
   body = []
 
-  valid = '<!doctype html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr><tr><td>11</td><td>&lt;script&gt;alert(&quot;This should not be displayed in a browser alert box.&quot;);&lt;/script&gt;</td></tr><tr><td>4</td><td>A bad random number generator: 1, 1, 1, 1, 1, 4.33e+67, 1, 1, 1</td></tr><tr><td>5</td><td>A computer program does what you tell it to do, not what you want it to do.</td></tr><tr><td>2</td><td>A computer scientist is someone who fixes things that aren&apos;t broken.</td></tr><tr><td>8</td><td>A list is only as strong as its weakest link. — Donald Knuth</td></tr><tr><td>0</td><td>Additional fortune added at request time.</td></tr><tr><td>3</td><td>After enough decimal places, nobody gives a damn.</td></tr><tr><td>7</td><td>Any program that runs right is obsolete.</td></tr><tr><td>10</td><td>Computers make very fast, very accurate mistakes.</td></tr><tr><td>6</td><td>Emacs is a nice operating system, but I prefer UNIX. — Tom Christaensen</td></tr><tr><td>9</td><td>Feature: A bug with seniority.</td></tr><tr><td>1</td><td>fortune: No such file or directory</td></tr><tr><td>12</td><td>フレームワークのベンチマーク</td></tr></table></body></html>'
+  valid = '''<!doctype html><html>
+<head><title>Fortunes</title></head>
+<body><table>
+<tr><th>id</th><th>message</th></tr>
+<tr><td>11</td><td>&lt;script&gt;alert(&quot;This should not be displayed in a browser alert box.&quot;);&lt;/script&gt;</td></tr>
+<tr><td>4</td><td>A bad random number generator: 1, 1, 1, 1, 1, 4.33e+67, 1, 1, 1</td></tr>
+<tr><td>5</td><td>A computer program does what you tell it to do, not what you want it to do.</td></tr>
+<tr><td>2</td><td>A computer scientist is someone who fixes things that aren&apos;t broken.</td></tr>
+<tr><td>8</td><td>A list is only as strong as its weakest link. — Donald Knuth</td></tr>
+<tr><td>0</td><td>Additional fortune added at request time.</td></tr>
+<tr><td>3</td><td>After enough decimal places, nobody gives a damn.</td></tr>
+<tr><td>7</td><td>Any program that runs right is obsolete.</td></tr>
+<tr><td>10</td><td>Computers make very fast, very accurate mistakes.</td></tr>
+<tr><td>6</td><td>Emacs is a nice operating system, but I prefer UNIX. — Tom Christaensen</td></tr>
+<tr><td>9</td><td>Feature: A bug with seniority.</td></tr>
+<tr><td>1</td><td>fortune: No such file or directory</td></tr>
+<tr><td>12</td><td>フレームワークのベンチマーク</td></tr>
+</table></body></html>'''
 
   # Is called when a doctype or other such tag is read in.
   # For our purposes, we assume this is only going to be
@@ -70,6 +87,10 @@ class FortuneHTMLParser(HTMLParser):
   # each one wrapped in "<" and ">".
   def handle_starttag(self, tag, attrs):
     self.body.append("<{t}>".format(t=tag))
+    
+    # Append a newline after the <table> and <html>
+    if tag.lower() == 'table' or tag.lower() == 'html':
+      self.body.append("\n")
 
   # This is called whenever data is presented inside of a
   # start and end tag. Generally, this will only ever be
@@ -106,15 +127,26 @@ class FortuneHTMLParser(HTMLParser):
   def handle_endtag(self, tag):
     self.body.append("</{t}>".format(t=tag))
 
+    # Append a newline after each </tr> and </head>
+    if tag.lower() == 'tr' or tag.lower() == 'head':
+      self.body.append("\n")
+
   # Returns whether the HTML input parsed by this parser
   # is valid against our known "fortune" spec.
   # The parsed data in 'body' is joined on empty strings
   # and checked for equality against our spec.
   def isValidFortune(self, out):
     body = ''.join(self.body)
-    diff = self.valid == body
-    if not diff:
+    same = self.valid == body
+    diff_lines = []
+    if not same:
+      out.write("Oh no! I compared %s\n\n\nto.....%s" % (self.valid, body))
       out.write("Fortune invalid. Diff following:\n")
-      diff_str = ''.join(unified_diff(self.valid.split(' '), body.split(' '), fromfile='Valid', tofile='Response', n=5))
-      out.write(diff_str)
-    return diff
+      headers_left = 3
+      for line in unified_diff(self.valid.split('\n'), body.split('\n'), fromfile='Valid', tofile='Response', n=0):
+        diff_lines.append(line)
+        out.write(line)
+        headers_left -= 1
+        if headers_left <= 0:
+          out.write('\n')
+    return (same, diff_lines)

+ 28 - 2
toolset/benchmark/test_types/fortune_type.py

@@ -28,8 +28,34 @@ class FortuneTestType(FrameworkTestType):
 
     parser = FortuneHTMLParser()
     parser.feed(body)
-    if parser.isValidFortune(self.out):
+    (valid, diff) = parser.isValidFortune(self.out)
+    if valid:
       return [('pass','',url)]
     else:
-      return [('fail','Invalid according to FortuneHTMLParser',url)]
+      failures = [('fail','Invalid according to FortuneHTMLParser',url)]
+      # Catch exceptions because we are relying on internal code
+      try:
+        # Parsing this: 
+        # --- Valid
+        # +++ Response
+        # @@ -1 +1 @@
+        #
+        # -<!doctype html><html><head><title>Fortunes</title></head><body><table>
+        # +<!doctype html><html><head><meta></meta><title>Fortunes</title></head><body><div><table>
+        # @@ -16 +16 @@
+        
+        current_neg = []
+        current_pos = []
+        for line in diff[3:]:
+          if line[0] == '+':
+            current_neg.append(line[1:])
+          elif line[0] == '-':
+            current_pos.append(line[1:])
+          elif line[0] == '@' or line == diff[:-1]:
+            failures.append( ('fail', 
+              "`%s` should be `%s`" % (''.join(current_neg), ''.join(current_pos)),
+              url) )
+      except: 
+        pass
+      return failures