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

guido at codespeak.net guido at codespeak.net
Mon Jan 22 16:07:56 CET 2007


Author: guido
Date: Mon Jan 22 16:07:54 2007
New Revision: 37145

Modified:
   py/dist/py/apigen/htmlgen.py
   py/dist/py/apigen/testing/test_apigen_example.py
   py/dist/py/apigen/testing/test_apigen_functional.py
Log:
Displaying arguments in a nicer fashion, displaying argument and return value
types, renamed the main namespace in the tests to 'main' to avoid confusion.


Modified: py/dist/py/apigen/htmlgen.py
==============================================================================
--- py/dist/py/apigen/htmlgen.py	(original)
+++ py/dist/py/apigen/htmlgen.py	Mon Jan 22 16:07:54 2007
@@ -11,21 +11,7 @@
 html = py.xml.html
 raw = py.xml.raw
 
-def create_namespace_tree(dotted_names):
-    """ creates a tree (in dict form) from a set of dotted names
-    """
-    ret = {}
-    for dn in dotted_names:
-        path = dn.split('.')
-        for i in xrange(len(path)):
-            ns = '.'.join(path[:i])
-            itempath = '.'.join(path[:i + 1])
-            if ns not in ret:
-                ret[ns] = []
-            if itempath not in ret[ns]:
-                ret[ns].append(itempath)
-    return ret
-
+# HTML related stuff
 class H(html):
     class Description(html.div):
         style = html.Style(margin_left='10em')
@@ -51,6 +37,12 @@
     class MethodDef(html.h2):
         pass
 
+    class FunctionDescription(Description):
+        pass
+
+    class FunctionDef(html.h2):
+        pass
+
     class ParameterDescription(html.div):
         pass
 
@@ -78,6 +70,14 @@
     class DirListItem(html.div):
         pass
 
+    class ValueDescList(html.ul):
+        def __init__(self, *args, **kwargs):
+            super(H.ValueDescList, self).__init__(*args, **kwargs)
+            self.insert(0, html.div('where:'))
+
+    class ValueDescItem(html.li):
+        pass
+
 def get_param_htmldesc(linker, func):
     """ get the html for the parameters of a function """
     import inspect
@@ -91,6 +91,7 @@
         navitem.attr.class_ = 'selected'
     return navitem
 
+# some helper functionality
 def source_dirs_files(fspath):
     """ returns a tuple (dirs, files) for fspath
 
@@ -114,6 +115,32 @@
             files.append(child)
     return sorted(dirs), sorted(files)
 
+def create_namespace_tree(dotted_names):
+    """ creates a tree (in dict form) from a set of dotted names
+    """
+    ret = {}
+    for dn in dotted_names:
+        path = dn.split('.')
+        for i in xrange(len(path)):
+            ns = '.'.join(path[:i])
+            itempath = '.'.join(path[:i + 1])
+            if ns not in ret:
+                ret[ns] = []
+            if itempath not in ret[ns]:
+                ret[ns].append(itempath)
+    return ret
+
+def wrap_page(project, title, contentel, navel, outputpath, stylesheeturl):
+    page = LayoutPage(project, title, nav=navel, encoding='UTF-8',
+                      stylesheeturl=stylesheeturl)
+    page.set_content(contentel)
+    here = py.magic.autopath().dirpath()
+    style = here.join('style.css').read()
+    outputpath.join('style.css').write(style)
+    return page
+
+# the PageBuilder classes take care of producing the docs (using the stuff
+# above)
 class AbstractPageBuilder(object):
     def write_page(self, title, reltargetpath, project, tag, nav):
         targetpath = self.base.join(reltargetpath)
@@ -257,36 +284,38 @@
         self.linker = linker
         self.dsa = dsa
         
-    def build_full_method_view(self, dotted_name):
+    def build_callable_view(self, dotted_name):
         """ build the html for a class method """
+        # XXX we may want to have seperate
         func = self.dsa.get_obj(dotted_name)
         sourcefile = inspect.getsourcefile(func)
-        params = get_param_htmldesc(self.linker, func)
         docstring = func.__doc__
         local_methodname = func.__name__
+        argdesc = get_param_htmldesc(self.linker, func)
+        valuedesc = self.build_callable_value_description(dotted_name)
+        
+        callable_source = self.dsa.get_function_source(dotted_name)
+        if callable_source:
+            csource = H.div(H.br(),
+                            H.div('source:'),
+                            H.SourceDef(H.pre(callable_source)))
+        else:
+            csource = H.SourceDef('could not get source')
+
         if sourcefile is not None:
-            sourcelink = H.a('source',
+            sourcelink = H.a('view source file',
                              href=self.linker.get_lazyhref(sourcefile))
         else:
             sourcelink = H.span('no source file available')
-        snippet = H.MethodDescription(
-            H.MethodDef(local_methodname, params, ":"),
-            sourcelink,
-            H.Docstring(docstring),
-        )
-        return snippet
 
-    def build_short_method_view(self, dotted_name):
-        """ build the html for a class method """
-        func = self.dsa.get_obj(dotted_name)
-        params = get_param_htmldesc(self.linker, func)
-        docstring = func.__doc__
-        local_methodname = func.__name__
-        snippet = H.MethodDescription(
-            H.MethodDef(local_methodname, params, ":"),
+        snippet = H.FunctionDescription(
+            H.FunctionDef(local_methodname, argdesc),
+            valuedesc,
             H.Docstring(docstring),
-            # XXX more info here...
+            csource,
+            sourcelink,
         )
+        
         return snippet
 
     def build_class_view(self, dotted_name):
@@ -324,8 +353,8 @@
         )
         snippet.append(H.h2('Functions:'))
         for method in methods:
-            snippet += self.build_short_method_view('%s.%s' % (dotted_name,
-                                                               method))
+            snippet += self.build_callable_view('%s.%s' % (dotted_name,
+                                                method))
         return snippet
 
     def build_namespace_view(self, namespace_dotted_name, item_dotted_names):
@@ -383,7 +412,7 @@
             parent_dotted_name, _ = split_of_last_part(dotted_name)
             module_dotted_name, _ = split_of_last_part(parent_dotted_name)
             sibling_dotted_names = namespace_tree[module_dotted_name]
-            tag = self.build_full_method_view(dotted_name)
+            tag = self.build_callable_view(dotted_name)
             nav = self.build_navigation(parent_dotted_name,
                                         sibling_dotted_names, dotted_name)
             reltargetpath = "api/%s.html" % (dotted_name,)
@@ -399,10 +428,10 @@
     def prepare_function_pages(self, namespace_tree, method_dotted_names):
         passed = []
         for dotted_name in method_dotted_names:
-            # XXX should we create a build_full_function_view instead?
+            # XXX should we create a build_function_view instead?
             parent_dotted_name, _ = split_of_last_part(dotted_name)
             sibling_dotted_names = namespace_tree[parent_dotted_name]
-            tag = self.build_full_method_view(dotted_name)
+            tag = self.build_callable_view(dotted_name)
             nav = self.build_navigation(parent_dotted_name,
                                         sibling_dotted_names, dotted_name)
             reltargetpath = "api/%s.html" % (dotted_name,)
@@ -437,7 +466,7 @@
     def build_namespace_pages(self, data, project):
         for dotted_name, tag, nav, reltargetpath in data:
             if dotted_name == '':
-                dotted_name = 'project root'
+                dotted_name = self.dsa.get_module_name().split('/')[-1]
             title = 'index of %s namespace' % (dotted_name,)
             self.write_page(title, reltargetpath, project, tag, nav)
 
@@ -473,12 +502,43 @@
                                                selected))
         return H.Navigation(*navitems)
 
-def wrap_page(project, title, contentel, navel, outputpath, stylesheeturl):
-    page = LayoutPage(project, title, nav=navel, encoding='UTF-8',
-                      stylesheeturl=stylesheeturl)
-    page.set_content(contentel)
-    here = py.magic.autopath().dirpath()
-    style = here.join('style.css').read()
-    outputpath.join('style.css').write(style)
-    return page
+    def build_callable_value_description(self, dotted_name):
+        args, retval = self.dsa.get_function_signature(dotted_name)
+        valuedesc = H.ValueDescList()
+        for name, _type in args + [('return value', retval)]:
+            l = self.process_type_link(_type)
+            items = []
+            next = "%s :: " % name
+            for item in l:
+                if isinstance(item, str):
+                    next += item
+                else:
+                    if next:
+                        items.append(next)
+                        next = ""
+                    items.append(item)
+            if next:
+                items.append(next)
+            valuedesc.append(H.ValueDescItem(*items))
+        return valuedesc
+
+    def process_type_link(self, _type):
+        # now we do simple type dispatching and provide a link in this case
+        lst = []
+        data = self.dsa.get_type_desc(_type)
+        if not data:
+            for i in _type.striter():
+                if isinstance(i, str):
+                    lst.append(i)
+                else:
+                    lst += self.process_type_link(i)
+            return lst
+        name, _desc_type, is_degenerated = data
+        if not is_degenerated:
+            linktarget = self.linker.get_lazyhref(name)
+            lst.append(H.a(str(_type), href=linktarget))
+        else:
+            # we should provide here some way of linking to sourcegen directly
+            lst.append(name)
+        return lst
 

Modified: py/dist/py/apigen/testing/test_apigen_example.py
==============================================================================
--- py/dist/py/apigen/testing/test_apigen_example.py	(original)
+++ py/dist/py/apigen/testing/test_apigen_example.py	Mon Jan 22 16:07:54 2007
@@ -3,6 +3,7 @@
 from py.__.apigen.linker import Linker
 from py.__.apigen.htmlgen import *
 from py.__.apigen.tracer.docstorage import DocStorage, DocStorageAccessor
+from py.__.apigen.tracer.tracer import Tracer
 from py.__.apigen.project import Project
 from py.__.test.web import webcheck
 from py.__.apigen.conftest import option
@@ -17,9 +18,10 @@
             else:
                 message = 'unexpected position: %s' % (newpos,)
             py.test.fail('string %r: %s' % (s, message))
+        currpos = newpos
 
-def setup_fs_project(tempname='apigen_example'):
-    temp = py.test.ensuretemp(tempname)
+def setup_fs_project():
+    temp = py.test.ensuretemp('apigen_example')
     temp.ensure("pkg/func.py").write(py.code.Source("""\
         def func(arg1):
             "docstring"
@@ -44,9 +46,9 @@
     temp.ensure("pkg/__init__.py").write(py.code.Source("""\
         from py.initpkg import initpkg
         initpkg(__name__, exportdefs = {
-            'pkg.sub.func': ("./func.py", "func"),
-            'pkg.SomeClass': ('./someclass.py', 'SomeClass'),
-            'pkg.SomeSubClass': ('./somesubclass.py', 'SomeSubClass'),
+            'main.sub.func': ("./func.py", "func"),
+            'main.SomeClass': ('./someclass.py', 'SomeClass'),
+            'main.SomeSubClass': ('./somesubclass.py', 'SomeSubClass'),
         })
     """))
     return temp, 'pkg'
@@ -57,7 +59,7 @@
     ds = DocStorage()
     ds.from_pkg(pkg)
     dsa = DocStorageAccessor(ds)
-    return dsa
+    return ds, dsa
 
 def _checkhtml(htmlstring):
     if isinstance(htmlstring, unicode):
@@ -79,7 +81,7 @@
 class AbstractBuilderTest(object):
     def setup_class(cls):
         cls.fs_root, cls.pkg_name = setup_fs_project()
-        cls.dsa = get_dsa(cls.fs_root, cls.pkg_name)
+        cls.ds, cls.dsa = get_dsa(cls.fs_root, cls.pkg_name)
         cls.project = Project()
 
     def setup_method(self, meth):
@@ -96,177 +98,194 @@
         self.spb = SourcePageBuilder(base, linker, self.fs_root)
 
 class TestApiPageBuilder(AbstractBuilderTest):
-    def test_build_full_method_view(self):
-        snippet = self.apb.build_full_method_view('pkg.sub.func')
+    def test_build_callable_view(self):
+        ds, dsa = get_dsa(self.fs_root, self.pkg_name)
+        t = Tracer(ds)
+        t.start_tracing()
+        pkg = __import__(self.pkg_name)
+        pkg.main.sub.func(10)
+        pkg.main.sub.func(pkg.main.SomeClass(10))
+        t.end_tracing()
+        apb = ApiPageBuilder(self.base, self.linker, dsa)
+        snippet = apb.build_callable_view('main.sub.func')
         html = snippet.unicode()
+        print html
+        run_string_sequence_test(html, [
+            'arg1 :: AnyOf(',
+            'href="',
+            'Class SomeClass',
+            'Int>',
+            'return value :: <None>',
+            'source:',
+            'def func(arg1):',
+        ])
         _checkhtmlsnippet(html)
 
     def test_build_function_pages(self):
-        namespace_tree = create_namespace_tree(['pkg.sub', 'pkg.sub.func',
-                                                'pkg.SomeClass',
-                                                'pkg.SomeSubClass'])
+        namespace_tree = create_namespace_tree(['main.sub', 'main.sub.func',
+                                                'main.SomeClass',
+                                                'main.SomeSubClass'])
         data = self.apb.prepare_function_pages(namespace_tree,
-                                               ['pkg.sub.func'])
+                                               ['main.sub.func'])
         self.apb.build_function_pages(data, self.project)
-        funcfile = self.base.join('api/pkg.sub.func.html')
+        funcfile = self.base.join('api/main.sub.func.html')
         assert funcfile.check()
         html = funcfile.read()
         _checkhtml(html)
 
     def test_build_class_view(self):
-        snippet = self.apb.build_class_view('pkg.SomeClass')
+        snippet = self.apb.build_class_view('main.SomeClass')
         html = snippet.unicode()
         _checkhtmlsnippet(html)
 
     def test_build_class_pages(self):
-        namespace_tree = create_namespace_tree(['pkg.SomeClass',
-                                                'pkg.SomeSubClass',
-                                                'pkg.sub.func'])
+        namespace_tree = create_namespace_tree(['main.SomeClass',
+                                                'main.SomeSubClass',
+                                                'main.sub.func'])
         data, methodsdata = self.apb.prepare_class_pages(namespace_tree,
-                                                         ['pkg.SomeClass',
-                                                          'pkg.SomeSubClass'])
+                                                         ['main.SomeClass',
+                                                          'main.SomeSubClass'])
         self.apb.build_class_pages(data, self.project)
-        clsfile = self.base.join('api/pkg.SomeClass.html')
+        clsfile = self.base.join('api/main.SomeClass.html')
         assert clsfile.check()
         html = clsfile.read()
         _checkhtml(html)
 
     def test_build_class_pages_nav_links(self):
-        namespace_tree = create_namespace_tree(['pkg.SomeClass',
-                                                'pkg.SomeSubClass',
-                                                'pkg.sub.func'])
+        namespace_tree = create_namespace_tree(['main.SomeClass',
+                                                'main.SomeSubClass',
+                                                'main.sub.func'])
         data, methodsdata = self.apb.prepare_class_pages(namespace_tree,
-                                                         ['pkg.SomeSubClass',
-                                                          'pkg.SomeClass'])
+                                                         ['main.SomeSubClass',
+                                                          'main.SomeClass'])
         # fake some stuff that would be built from other methods
         self.linker.set_link('', 'api/index.html')
-        self.linker.set_link('pkg', 'api/pkg.html')
+        self.linker.set_link('main', 'api/main.html')
         self.apb.build_class_pages(data, self.project)
-        clsfile = self.base.join('api/pkg.SomeClass.html')
+        clsfile = self.base.join('api/main.SomeClass.html')
         assert clsfile.check()
         html = clsfile.read()
         print html
-        # note that the root and the first level both have the same name (pkg)
-        # in our example project (XXX fixme!!)
         run_string_sequence_test(html, [
             'href="../style.css"',
             'href="index.html">pkg',
-            'href="pkg.html">pkg',
-            'href="pkg.SomeClass.html">SomeClass',
-            'href="pkg.SomeSubClass.html">SomeSubClass',
+            'href="main.html">main',
+            'href="main.SomeClass.html">SomeClass',
+            'href="main.SomeSubClass.html">SomeSubClass',
         ])
-        assert not 'href="pkg.sub.func.html"' in html
+        assert not 'href="main.sub.func.html"' in html
         py.test.skip('WOP from here')
-        assert 'href="pkg.sub.html">sub' in html
+        assert 'href="main.sub.html">sub' in html
         _checkhtml(html)
 
     def test_build_class_pages_base_link(self):
-        namespace_tree = create_namespace_tree(['pkg.SomeClass',
-                                                'pkg.SomeSubClass',
-                                                'pkg.sub.func'])
+        namespace_tree = create_namespace_tree(['main.SomeClass',
+                                                'main.SomeSubClass',
+                                                'main.sub.func'])
         data, methodsdata = self.apb.prepare_class_pages(namespace_tree,
-                                                        ['pkg.SomeSubClass',
-                                                         'pkg.SomeClass'])
+                                                        ['main.SomeSubClass',
+                                                         'main.SomeClass'])
         self.apb.build_class_pages(data, self.project)
-        clsfile = self.base.join('api/pkg.SomeSubClass.html')
+        clsfile = self.base.join('api/main.SomeSubClass.html')
         assert clsfile.check()
         html = clsfile.read()
         print html
         run_string_sequence_test(html, [
             'href="../style.css"',
-            'href="pkg.SomeClass.html">pkg.SomeClass',
+            'href="main.SomeClass.html">main.SomeClass',
         ])
         _checkhtml(html)
 
     def test_source_links(self):
-        namespace_tree = create_namespace_tree(['pkg.SomeClass',
-                                                'pkg.SomeSubClass',
-                                                'pkg.sub.func'])
+        namespace_tree = create_namespace_tree(['main.SomeClass',
+                                                'main.SomeSubClass',
+                                                'main.sub.func'])
         data, methodsdata = self.apb.prepare_class_pages(namespace_tree,
-                                                         ['pkg.SomeSubClass',
-                                                          'pkg.SomeClass'])
+                                                         ['main.SomeSubClass',
+                                                          'main.SomeClass'])
         sourcedata = self.spb.prepare_pages(self.fs_root)
         self.apb.build_class_pages(data, self.project)
         self.spb.build_pages(sourcedata, self.project, self.fs_root)
-        funchtml = self.base.join('api/pkg.SomeClass.html').read()
+        funchtml = self.base.join('api/main.SomeClass.html').read()
         assert funchtml.find('href="../source/pkg/someclass.py.html"') > -1
         _checkhtml(funchtml)
 
     def test_build_namespace_pages_index(self):
-        namespace_tree = create_namespace_tree(['pkg.sub', 'pkg.sub.func',
-                                                'pkg.SomeClass',
-                                                'pkg.SomeSubClass'])
+        namespace_tree = create_namespace_tree(['main.sub', 'main.sub.func',
+                                                'main.SomeClass',
+                                                'main.SomeSubClass'])
         data = self.apb.prepare_namespace_pages(namespace_tree)
         self.apb.prepare_class_pages(namespace_tree,
-                                     ['pkg.SomeClass',
-                                      'pkg.SomeSubClass'])
-        self.apb.prepare_function_pages(namespace_tree, ['pkg.sub.func'])
+                                     ['main.SomeClass',
+                                      'main.SomeSubClass'])
+        self.apb.prepare_function_pages(namespace_tree, ['main.sub.func'])
         self.apb.build_namespace_pages(data, self.project)
-        pkgfile = self.base.join('api/pkg.html')
+        pkgfile = self.base.join('api/index.html')
         assert pkgfile.check()
         html = pkgfile.read()
+        assert 'index of project pkg namespace'
         _checkhtml(html)
 
     def test_build_namespace_pages_subnamespace(self):
-        namespace_tree = create_namespace_tree(['pkg.sub', 'pkg.sub.func',
-                                                'pkg.SomeClass',
-                                                'pkg.SomeSubClass'])
+        namespace_tree = create_namespace_tree(['main.sub', 'main.sub.func',
+                                                'main.SomeClass',
+                                                'main.SomeSubClass'])
         data = self.apb.prepare_namespace_pages(namespace_tree)
         self.apb.build_namespace_pages(data, self.project)
-        subfile = self.base.join('api/pkg.sub.html')
+        subfile = self.base.join('api/main.sub.html')
         assert subfile.check()
         html = subfile.read()
         _checkhtml(html)
 
     def test_build_function_api_pages_nav(self):
-        namespace_tree = create_namespace_tree(['pkg.sub', 'pkg.sub.func',
-                                                'pkg.SomeClass',
-                                                'pkg.SomeSubClass'])
+        namespace_tree = create_namespace_tree(['main.sub', 'main.sub.func',
+                                                'main.SomeClass',
+                                                'main.SomeSubClass'])
         data = self.apb.prepare_function_pages(namespace_tree,
-                                                   ['pkg.sub.func'])
+                                                   ['main.sub.func'])
         self.linker.set_link('', 'api/index.html')
-        self.linker.set_link('pkg', 'api/pkg.html')
-        self.linker.set_link('pkg.sub', 'api/pkg.sub.html')
+        self.linker.set_link('main', 'api/main.html')
+        self.linker.set_link('main.sub', 'api/main.sub.html')
         self.apb.build_function_pages(data, self.project)
-        funcfile = self.base.join('api/pkg.sub.func.html')
+        funcfile = self.base.join('api/main.sub.func.html')
         html = funcfile.read()
         print html
         run_string_sequence_test(html, [
             '<a href="index.html">',
-            '<a href="pkg.html">',
-            '<a href="pkg.sub.html">',
-            '<a href="pkg.sub.func.html">',
+            '<a href="main.html">',
+            '<a href="main.sub.html">',
+            '<a href="main.sub.func.html">',
         ])
         _checkhtml(html)
 
     def test_build_function_navigation(self):
-        namespace_tree = create_namespace_tree(['pkg.sub', 'pkg.sub.func',
-                                                'pkg.SomeClass',
-                                                'pkg.SomeSubClass'])
+        namespace_tree = create_namespace_tree(['main.sub', 'main.sub.func',
+                                                'main.SomeClass',
+                                                'main.SomeSubClass'])
         self.apb.prepare_namespace_pages(namespace_tree)
-        self.apb.prepare_function_pages(namespace_tree, ['pkg.sub.func'])
-        nav = self.apb.build_navigation('pkg.sub', ['pkg.sub.func'],
-                                        'pkg.sub.func')
+        self.apb.prepare_function_pages(namespace_tree, ['main.sub.func'])
+        nav = self.apb.build_navigation('main.sub', ['main.sub.func'],
+                                        'main.sub.func')
         html = nav.unicode(indent=0)
         print html.encode('UTF-8')
         assert (u'<div><a href="api/index.html">pkg</a></div>'
-                u'<div>\xa0\xa0<a href="api/pkg.html">pkg</a></div>'
+                u'<div>\xa0\xa0<a href="api/main.html">main</a></div>'
                 u'<div>\xa0\xa0\xa0\xa0'
-                    u'<a href="api/pkg.sub.html">sub</a></div>'
+                    u'<a href="api/main.sub.html">sub</a></div>'
                 u'<div class="selected">\xa0\xa0\xa0\xa0\xa0\xa0'
-                    u'<a href="api/pkg.sub.func.html">func</a></div>'
+                    u'<a href="api/main.sub.func.html">func</a></div>'
         ) in html
 
     def test_build_root_namespace_view(self):
-        namespace_tree = create_namespace_tree(['pkg.sub', 'pkg.sub.func',
-                                                'pkg.SomeClass',
-                                                'pkg.SomeSubClass'])
+        namespace_tree = create_namespace_tree(['main.sub', 'main.sub.func',
+                                                'main.SomeClass',
+                                                'main.SomeSubClass'])
         data = self.apb.prepare_namespace_pages(namespace_tree)
         self.apb.build_namespace_pages(data, self.project)
         rootfile = self.base.join('api/index.html')
         assert rootfile.check()
         html = rootfile.read()
-        assert '<a href="pkg.html">' in html
+        assert '<a href="main.html">' in html
         _checkhtml(html)
 
 class TestSourcePageBuilder(AbstractBuilderTest):

Modified: py/dist/py/apigen/testing/test_apigen_functional.py
==============================================================================
--- py/dist/py/apigen/testing/test_apigen_functional.py	(original)
+++ py/dist/py/apigen/testing/test_apigen_functional.py	Mon Jan 22 16:07:54 2007
@@ -4,46 +4,106 @@
 """
 
 import py
-from test_apigen_example import setup_fs_project
+
+def setup_fs_project():
+    temp = py.test.ensuretemp('apigen_functional')
+    temp.ensure("pkg/func.py").write(py.code.Source("""\
+        def func(arg1):
+            "docstring"
+
+        def func_2(arg1, arg2):
+            return arg1(arg2)
+    """))
+    temp.ensure('pkg/sometestclass.py').write(py.code.Source("""\
+        class SomeTestClass(object):
+            " docstring sometestclass "
+            def __init__(self, somevar):
+                self.somevar = somevar
+                
+            def get_somevar(self):
+                " get_somevar docstring "
+                return self.somevar
+    """))
+    temp.ensure('pkg/sometestsubclass.py').write(py.code.Source("""\
+        from sometestclass import SomeTestClass
+        class SomeTestSubClass(SomeTestClass):
+            " docstring sometestsubclass "
+            def get_somevar(self):
+                return self.somevar + 1
+    """))
+    temp.ensure("pkg/__init__.py").write(py.code.Source("""\
+        from py.initpkg import initpkg
+        initpkg(__name__, exportdefs = {
+            'main.sub.func': ("./func.py", "func"),
+            'main.func': ("./func.py", "func_2"),
+            'main.SomeTestClass': ('./sometestclass.py', 'SomeTestClass'),
+            'main.SomeTestSubClass': ('./sometestsubclass.py', 'SomeTestSubClass'),
+        })
+    """))
+    temp.ensure('pkg/test/test_pkg.py').write(py.code.Source("""\
+        import py
+        py.std.sys.path.insert(0,
+            py.magic.autopath().dirpath().dirpath().dirpath().strpath)
+        import pkg
+
+        # this mainly exists to provide some data to the tracer
+        def test_pkg():
+            s = pkg.main.SomeTestClass(10)
+            assert s.get_somevar() == 10
+            s = pkg.main.SomeTestClass('10')
+            assert s.get_somevar() == '10'
+            s = pkg.main.SomeTestSubClass(10)
+            assert s.get_somevar() == 11
+            s = pkg.main.SomeTestSubClass('10')
+            py.test.raises(TypeError, 's.get_somevar()')
+            assert pkg.main.sub.func(10) is None
+            assert pkg.main.sub.func(20) is None
+            s = pkg.main.func(pkg.main.SomeTestClass, 10)
+            assert isinstance(s, pkg.main.SomeTestClass)
+    """))
+    return temp, 'pkg'
 
 def test_apigen_functional():
-    fs_root, package_name = setup_fs_project(
-                                        'test_apigen_functional')
+    fs_root, package_name = setup_fs_project()
     tempdir = py.test.ensuretemp('test_apigen_functional_results')
     parentdir = py.magic.autopath().dirpath().dirpath()
     pkgdir = fs_root.join('pkg')
-    output = py.process.cmdexec(
-        'APIGEN_TARGET="%s" py.test --session=L --apigen="%s/apigen.py" "%s"' % (
-            tempdir, parentdir, pkgdir))
+    try:
+        output = py.process.cmdexec('APIGEN_TARGET="%s" py.test --session=L '
+                                    '--apigen="%s/apigen.py" "%s"' % (
+                                        tempdir, parentdir, pkgdir))
+    except py.error.Error, e:
+        print e.out
+        raise
     assert output.lower().find('traceback') == -1
 
     # just some quick content checks
     apidir = tempdir.join('api')
     assert apidir.check(dir=True)
-    someclass_api = apidir.join('pkg.SomeClass.html')
-    assert someclass_api.check(file=True)
-    html = someclass_api.read()
-    assert '<a href="pkg.SomeClass.html">SomeClass</a>' in html
+    sometestclass_api = apidir.join('main.SomeTestClass.html')
+    assert sometestclass_api.check(file=True)
+    html = sometestclass_api.read()
+    assert '<a href="main.SomeTestClass.html">SomeTestClass</a>' in html
     # XXX not linking to method files anymore
-    #someclass_init_api = apidir.join('pkg.SomeClass.__init__.html')
-    #assert someclass_init_api.check(file=True)
-    #assert someclass_init_api.read().find(
-    #        '<a href="pkg.SomeClass.__init__.html">__init__</a>') > -1
-    namespace_api = apidir.join('pkg.html')
+    #sometestclass_init_api = apidir.join('main.SomeTestClass.__init__.html')
+    #assert sometestclass_init_api.check(file=True)
+    #assert sometestclass_init_api.read().find(
+    #        '<a href="main.SomeTestClass.__init__.html">__init__</a>') > -1
+    namespace_api = apidir.join('main.html')
     assert namespace_api.check(file=True)
     html = namespace_api.read()
-    assert '<a href="pkg.SomeClass.html">SomeClass</a>' in html
+    assert '<a href="main.SomeTestClass.html">SomeTestClass</a>' in html
 
     sourcedir = tempdir.join('source')
     assert sourcedir.check(dir=True)
-    someclass_source = sourcedir.join('someclass.py.html')
-    assert someclass_source.check(file=True)
-    html = someclass_source.read()
-    assert '<div class="project_title">sources for someclass.py</div>' in html
+    sometestclass_source = sourcedir.join('sometestclass.py.html')
+    assert sometestclass_source.check(file=True)
+    html = sometestclass_source.read()
+    assert '<div class="project_title">sources for sometestclass.py</div>' in html
 
     # XXX later...
     #index = sourcedir.join('index.html')
     #assert index.check(file=True)
     #html = index.read()
-    #assert '<a href="pkg/index.html">pkg</a>' in html
+    #assert '<a href="main/index.html">main</a>' in html
 



More information about the pytest-commit mailing list