[py-svn] r34918 - in py/dist/py/apigen/source: . testing

fijal at codespeak.net fijal at codespeak.net
Thu Nov 23 21:51:29 CET 2006


Author: fijal
Date: Thu Nov 23 21:51:21 2006
New Revision: 34918

Added:
   py/dist/py/apigen/source/html.py   (contents, props changed)
   py/dist/py/apigen/source/testing/test_html.py   (contents, props changed)
Modified:
   py/dist/py/apigen/source/browser.py
Log:
(fijal, guido) - HTML generation out of source browser


Modified: py/dist/py/apigen/source/browser.py
==============================================================================
--- py/dist/py/apigen/source/browser.py	(original)
+++ py/dist/py/apigen/source/browser.py	Thu Nov 23 21:51:21 2006
@@ -12,7 +12,10 @@
 
 from py.__.path.common import PathBase
 
-class Module(object):
+class BaseElem(object):
+    pass # purely for testing isinstance
+
+class Module(BaseElem):
     def __init__(self, path, _dict):
         self.path = path
         self.dict = _dict
@@ -22,6 +25,9 @@
             return self.dict[attr]
         except KeyError:
             raise AttributeError(attr)
+    
+    def get_children(self):
+        return self.dict.values()
 
 def get_endline(start, lst):
     l = reversed(lst)
@@ -33,13 +39,13 @@
             return end_ch
     return start
 
-class Function(object):
+class Function(BaseElem):
     def __init__(self, name, firstlineno, endlineno):
         self.firstlineno = firstlineno
         self.endlineno = endlineno
         self.name = name
 
-class Method(object):
+class Method(BaseElem):
     def __init__(self, name, firstlineno, endlineno):
         self.name = name
         self.firstlineno = firstlineno
@@ -62,7 +68,7 @@
         cls_ast.code.nodes if isinstance(i, ast.Function)])
     return Class(name, startline, endline, bases, methods)
 
-class Class(object):
+class Class(BaseElem):
     def __init__(self, name, firstlineno, endlineno, bases, methods):
         self.bases = bases
         self.firstlineno = firstlineno
@@ -75,9 +81,13 @@
             return self.methods[attr]
         except KeyError:
             raise AttributeError(attr)
+    
+    def get_children(self):
+        return self.methods.values()
 
 def parse_path(path):
-    assert isinstance(path, PathBase), "Cannot work on files directly"
+    if not isinstance(path, PathBase):
+        path = py.path.local(path)
     buf = path.open().read()
     st = parse(buf)
     # first go - we get all functions and classes defined on top-level

Added: py/dist/py/apigen/source/html.py
==============================================================================
--- (empty file)
+++ py/dist/py/apigen/source/html.py	Thu Nov 23 21:51:21 2006
@@ -0,0 +1,59 @@
+
+""" html - generating ad-hoc html out of source browser
+"""
+
+from py.xml import html
+from compiler import ast
+
+class HtmlEnchanter(object):
+    def __init__(self, mod):
+        self.mod = mod
+        self.create_caches()
+    
+    def create_caches(self):
+        mod = self.mod
+        linecache = {}
+        for item in mod.get_children():
+            linecache[item.firstlineno] = item
+        self.linecache = linecache
+    
+    def enchant_row(self, num, row):
+        # add some informations to row, like functions defined in that line, etc.
+        try:
+            item = self.linecache[num]
+            # XXX: this should not be assertion, rather check, but we want to
+            #      know if stuff is working
+            pos = row.find(item.name)
+            assert pos != -1
+            end = len(item.name) + pos
+            return [row[:pos], html.a(row[pos:end], href="#" + item.name, 
+                name=item.name), row[end:]]
+        except KeyError:
+            return [row] # no more info
+
+def make_code(lst):
+    # I HATE HTML, I HATE HTML
+    output = []
+    for elem in lst:
+        if isinstance(elem, str):
+            output.append(html.code(elem))
+        else:
+            output.append(elem)
+    return output
+
+def create_html(mod):
+    # out is some kind of stream
+    #*[html.tr(html.td(i.name)) for i in mod.get_children()]
+    lines = mod.path.open().readlines()
+    
+    enchanter = HtmlEnchanter(mod)
+    rows = [enchanter.enchant_row(num + 1, row[:-1]) for num, row in enumerate(lines)]
+    html_rows = [html.tr(html.td(html.pre(num + 1), html.td(html.pre(*i)))) \
+        for num, i in enumerate(rows)]
+    
+    output = html.table(
+        html.tbody(
+            *html_rows
+        )
+    )
+    return output

Added: py/dist/py/apigen/source/testing/test_html.py
==============================================================================
--- (empty file)
+++ py/dist/py/apigen/source/testing/test_html.py	Thu Nov 23 21:51:21 2006
@@ -0,0 +1,47 @@
+
+""" test of html generation
+"""
+
+from py.__.apigen.source.html import create_html
+from py.__.apigen.source.browser import parse_path
+
+import py
+import os
+
+def create_html_and_show(path):
+    mod = parse_path(path)
+    html = create_html(mod)
+    testfile = py.test.ensuretemp("htmloutput").ensure("test.html")
+    testfile.write(unicode(html))
+    return testfile
+
+def test_basic():
+    tmp = py.test.ensuretemp("sourcehtml")
+    inp = tmp.ensure("one.py")
+    inp.write(py.code.Source("""
+    def func_one():
+        pass
+    
+    def func_two(x, y):
+        x = 1
+        y = 2
+        return x + y
+    
+    class B:
+        pass
+    
+    class A(B):
+        def meth1(self):
+            pass
+        
+        def meth2(self):
+            pass
+    """))
+    
+    testfile = create_html_and_show(inp)
+    data = testfile.open().read()
+    assert data.find('<a href="#func_one"') != -1
+    assert data.find('<a href="#func_two"') != -1
+    assert data.find('<a href="#B"') != -1
+    assert data.find('<a href="#A"') != -1
+    



More information about the pytest-commit mailing list