[svn r37395] Fixed some small issues in source nav, turned namespace_tree into an instance
var (finally! :), changed the api nav so it now shows the full tree with the current item unfolded + siblings of itself and all parents (+ children if it's a namespace item). --HG-- branch : trunk
This commit is contained in:
		
							parent
							
								
									b67ef229df
								
							
						
					
					
						commit
						3c08f6a614
					
				|  | @ -14,11 +14,7 @@ from py.__.apigen import project | |||
| def get_documentable_items(pkgdir): | ||||
|     sys.path.insert(0, str(pkgdir.dirpath())) | ||||
|     rootmod = __import__(pkgdir.basename) | ||||
|     #rootmod = import_pkgdir(pkgdir) | ||||
|     if hasattr(rootmod, '__package__'): | ||||
|     return rootmod | ||||
|     # XXX fix non-initpkg situations(?) | ||||
|     return {} | ||||
| 
 | ||||
| def build(pkgdir, dsa): | ||||
|     l = linker.Linker() | ||||
|  | @ -32,15 +28,14 @@ def build(pkgdir, dsa): | |||
| 
 | ||||
|     all_names = dsa._get_names(filter=lambda x, y: True) | ||||
|     namespace_tree = htmlgen.create_namespace_tree(all_names) | ||||
|     apb = htmlgen.ApiPageBuilder(targetdir, l, dsa, pkgdir) | ||||
|     apb = htmlgen.ApiPageBuilder(targetdir, l, dsa, pkgdir, namespace_tree) | ||||
|     spb = htmlgen.SourcePageBuilder(targetdir, l, pkgdir) | ||||
| 
 | ||||
|     ns_data = apb.prepare_namespace_pages(namespace_tree) | ||||
|     ns_data = apb.prepare_namespace_pages() | ||||
|     class_names = dsa.get_class_names() | ||||
|     class_data = apb.prepare_class_pages(namespace_tree, | ||||
|                                                       class_names) | ||||
|     class_data = apb.prepare_class_pages(class_names) | ||||
|     function_names = dsa.get_function_names() | ||||
|     func_data = apb.prepare_function_pages(namespace_tree, function_names) | ||||
|     func_data = apb.prepare_function_pages(function_names) | ||||
|     source_data = spb.prepare_pages(pkgdir) | ||||
| 
 | ||||
|     apb.build_namespace_pages(ns_data, proj) | ||||
|  |  | |||
|  | @ -180,11 +180,12 @@ class SourcePageBuilder(AbstractPageBuilder): | |||
|         path = relpath.split(os.path.sep) | ||||
|         indent = 0 | ||||
|         # build links to parents | ||||
|         if relpath != '': | ||||
|             for i in xrange(len(path)): | ||||
|                 dirpath = os.path.sep.join(path[:i]) | ||||
|                 abspath = self.projroot.join(dirpath).strpath | ||||
|                 if i == 0: | ||||
|                 text = 'root' | ||||
|                     text = self.projroot.basename | ||||
|                 else: | ||||
|                     text = path[i-1] | ||||
|                 nav.append(build_navitem_html(self.linker, text, abspath, | ||||
|  | @ -296,12 +297,13 @@ class SourcePageBuilder(AbstractPageBuilder): | |||
| 
 | ||||
| class ApiPageBuilder(AbstractPageBuilder): | ||||
|     """ builds the html for an api docs page """ | ||||
|     def __init__(self, base, linker, dsa, projroot): | ||||
|     def __init__(self, base, linker, dsa, projroot, namespace_tree): | ||||
|         self.base = base | ||||
|         self.linker = linker | ||||
|         self.dsa = dsa | ||||
|         self.projroot = projroot | ||||
|         self.projpath = py.path.local(projroot) | ||||
|         self.namespace_tree = namespace_tree | ||||
|          | ||||
|     def build_callable_view(self, dotted_name): | ||||
|         """ build the html for a class method """ | ||||
|  | @ -428,18 +430,17 @@ class ApiPageBuilder(AbstractPageBuilder): | |||
|             ) | ||||
|         return snippet | ||||
| 
 | ||||
|     def prepare_class_pages(self, namespace_tree, classes_dotted_names): | ||||
|     def prepare_class_pages(self, classes_dotted_names): | ||||
|         passed = [] | ||||
|         for dotted_name in sorted(classes_dotted_names): | ||||
|             parent_dotted_name, _ = split_of_last_part(dotted_name) | ||||
|             try: | ||||
|                 sibling_dotted_names = namespace_tree[parent_dotted_name] | ||||
|                 sibling_dotted_names = self.namespace_tree[parent_dotted_name] | ||||
|             except KeyError: | ||||
|                 # no siblings (built-in module or sth) | ||||
|                 sibling_dotted_names = [] | ||||
|             tag = H.Content(self.build_class_view(dotted_name)) | ||||
|             nav = self.build_navigation(parent_dotted_name, | ||||
|                                         sibling_dotted_names, dotted_name) | ||||
|             nav = self.build_navigation(dotted_name, False) | ||||
|             reltargetpath = "api/%s.html" % (dotted_name,) | ||||
|             self.linker.set_link(dotted_name, reltargetpath) | ||||
|             passed.append((dotted_name, tag, nav, reltargetpath)) | ||||
|  | @ -451,17 +452,16 @@ class ApiPageBuilder(AbstractPageBuilder): | |||
|             title = 'api documentation for %s' % (dotted_name,) | ||||
|             self.write_page(title, reltargetpath, project, tag, nav) | ||||
| 
 | ||||
|     def prepare_method_pages(self, namespace_tree, method_dotted_names): | ||||
|     def prepare_method_pages(self, method_dotted_names): | ||||
|         # XXX note that even though these pages are still built, there's no nav | ||||
|         # pointing to them anymore... | ||||
|         passed = [] | ||||
|         for dotted_name in sorted(method_dotted_names): | ||||
|             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] | ||||
|             sibling_dotted_names = self.namespace_tree[module_dotted_name] | ||||
|             tag = self.build_callable_view(dotted_name) | ||||
|             nav = self.build_navigation(parent_dotted_name, | ||||
|                                         sibling_dotted_names, dotted_name) | ||||
|             nav = self.build_navigation(dotted_name, False) | ||||
|             reltargetpath = "api/%s.html" % (dotted_name,) | ||||
|             self.linker.set_link(dotted_name, reltargetpath) | ||||
|             passed.append((dotted_name, tag, nav, reltargetpath)) | ||||
|  | @ -472,15 +472,14 @@ class ApiPageBuilder(AbstractPageBuilder): | |||
|             title = 'api documentation for %s' % (dotted_name,) | ||||
|             self.write_page(title, reltargetpath, project, tag, nav) | ||||
| 
 | ||||
|     def prepare_function_pages(self, namespace_tree, method_dotted_names): | ||||
|     def prepare_function_pages(self, method_dotted_names): | ||||
|         passed = [] | ||||
|         for dotted_name in sorted(method_dotted_names): | ||||
|             # 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] | ||||
|             sibling_dotted_names = self.namespace_tree[parent_dotted_name] | ||||
|             tag = H.Content(self.build_callable_view(dotted_name)) | ||||
|             nav = self.build_navigation(parent_dotted_name, | ||||
|                                         sibling_dotted_names, dotted_name) | ||||
|             nav = self.build_navigation(dotted_name, False) | ||||
|             reltargetpath = "api/%s.html" % (dotted_name,) | ||||
|             self.linker.set_link(dotted_name, reltargetpath) | ||||
|             passed.append((dotted_name, tag, nav, reltargetpath)) | ||||
|  | @ -491,22 +490,21 @@ class ApiPageBuilder(AbstractPageBuilder): | |||
|             title = 'api documentation for %s' % (dotted_name,) | ||||
|             self.write_page(title, reltargetpath, project, tag, nav) | ||||
| 
 | ||||
|     def prepare_namespace_pages(self, namespace_tree): | ||||
|     def prepare_namespace_pages(self): | ||||
|         passed = [] | ||||
|         module_name = self.dsa.get_module_name().split('/')[-1] | ||||
| 
 | ||||
|         names = namespace_tree.keys() | ||||
|         names = self.namespace_tree.keys() | ||||
|         names.sort() | ||||
|         function_names = self.dsa.get_function_names() | ||||
|         class_names = self.dsa.get_class_names() | ||||
|         for dotted_name in sorted(names): | ||||
|             if dotted_name in function_names or dotted_name in class_names: | ||||
|                 continue | ||||
|             subitem_dotted_names = namespace_tree[dotted_name] | ||||
|             subitem_dotted_names = self.namespace_tree[dotted_name] | ||||
|             tag = H.Content(self.build_namespace_view(dotted_name, | ||||
|                                                       subitem_dotted_names)) | ||||
|             nav = self.build_navigation(dotted_name, subitem_dotted_names, | ||||
|                                         dotted_name) | ||||
|             nav = self.build_navigation(dotted_name, True) | ||||
|             if dotted_name == '': | ||||
|                 reltargetpath = 'api/index.html' | ||||
|             else: | ||||
|  | @ -522,7 +520,39 @@ class ApiPageBuilder(AbstractPageBuilder): | |||
|             title = 'index of %s namespace' % (dotted_name,) | ||||
|             self.write_page(title, reltargetpath, project, tag, nav) | ||||
| 
 | ||||
|     def build_navigation(self, dotted_name, item_dotted_names, selection): | ||||
|     def build_navigation(self, dotted_name, build_children=True): | ||||
|         navitems = [] | ||||
| 
 | ||||
|         # top namespace, index.html | ||||
|         module_name = self.dsa.get_module_name().split('/')[-1] | ||||
|         navitems.append(build_navitem_html(self.linker, module_name, '', 0, | ||||
|                                            True)) | ||||
|         def build_nav_level(dotted_name, depth=1): | ||||
|             navitems = [] | ||||
|             path = dotted_name.split('.')[:depth] | ||||
|             siblings = self.namespace_tree.get('.'.join(path[:-1])) | ||||
|             for dn in sorted(siblings): | ||||
|                 selected = dn == '.'.join(path) | ||||
|                 sibpath = dn.split('.') | ||||
|                 navitems.append(build_navitem_html(self.linker, sibpath[-1], | ||||
|                                                    dn, depth, | ||||
|                                                    selected)) | ||||
|                 if selected: | ||||
|                     lastlevel = dn.count('.') == dotted_name.count('.') | ||||
|                     if not lastlevel: | ||||
|                         navitems += build_nav_level(dotted_name, depth+1) | ||||
|                     elif lastlevel and build_children: | ||||
|                         # XXX hack | ||||
|                         navitems += build_nav_level('%s.' % (dotted_name,), | ||||
|                                                     depth+2) | ||||
| 
 | ||||
|             return navitems | ||||
| 
 | ||||
|         navitems += build_nav_level(dotted_name) | ||||
|         return H.Navigation(*navitems) | ||||
| 
 | ||||
| 
 | ||||
|      | ||||
|         navitems = [] | ||||
| 
 | ||||
|         # top namespace, index.html | ||||
|  |  | |||
|  | @ -104,15 +104,19 @@ class AbstractBuilderTest(object): | |||
|         self.base = base = py.test.ensuretemp('%s_%s' % ( | ||||
|                             self.__class__.__name__, meth.im_func.func_name)) | ||||
|         self.linker = linker = LinkerForTests() | ||||
|         self.apb = ApiPageBuilder(base, linker, self.dsa, self.fs_root) | ||||
|         self.spb = SourcePageBuilder(base, linker, self.fs_root) | ||||
|         self.namespace_tree = create_namespace_tree(['main.sub', | ||||
|         namespace_tree = create_namespace_tree(['main.sub', | ||||
|                                                 'main.sub.func', | ||||
|                                                 'main.SomeClass', | ||||
|                                                 'main.SomeSubClass', | ||||
|                                                 'main.SomeInstance', | ||||
|                                                 'other.foo', | ||||
|                                                 'other.bar']) | ||||
|         self.namespace_tree = namespace_tree | ||||
|         self.apb = ApiPageBuilder(base, linker, self.dsa, | ||||
|                                   self.fs_root.join(self.pkg_name), | ||||
|                                   namespace_tree) | ||||
|         self.spb = SourcePageBuilder(base, linker, | ||||
|                                      self.fs_root.join(self.pkg_name)) | ||||
| 
 | ||||
| class TestApiPageBuilder(AbstractBuilderTest): | ||||
|     def test_build_callable_view(self): | ||||
|  | @ -123,7 +127,8 @@ class TestApiPageBuilder(AbstractBuilderTest): | |||
|         pkg.main.sub.func(10) | ||||
|         pkg.main.sub.func(pkg.main.SomeClass(10)) | ||||
|         t.end_tracing() | ||||
|         apb = ApiPageBuilder(self.base, self.linker, dsa, self.fs_root) | ||||
|         apb = ApiPageBuilder(self.base, self.linker, dsa, self.fs_root, | ||||
|                              self.namespace_tree) | ||||
|         snippet = apb.build_callable_view('main.sub.func') | ||||
|         html = snippet.unicode() | ||||
|         print html | ||||
|  | @ -149,8 +154,7 @@ class TestApiPageBuilder(AbstractBuilderTest): | |||
|         _checkhtmlsnippet(html) | ||||
| 
 | ||||
|     def test_build_function_pages(self): | ||||
|         data = self.apb.prepare_function_pages(self.namespace_tree, | ||||
|                                                ['main.sub.func']) | ||||
|         data = self.apb.prepare_function_pages(['main.sub.func']) | ||||
|         self.apb.build_function_pages(data, self.project) | ||||
|         funcfile = self.base.join('api/main.sub.func.html') | ||||
|         assert funcfile.check() | ||||
|  | @ -163,8 +167,7 @@ class TestApiPageBuilder(AbstractBuilderTest): | |||
|         _checkhtmlsnippet(html) | ||||
| 
 | ||||
|     def test_build_class_pages(self): | ||||
|         data = self.apb.prepare_class_pages(self.namespace_tree, | ||||
|                                             ['main.SomeClass', | ||||
|         data = self.apb.prepare_class_pages(['main.SomeClass', | ||||
|                                              'main.SomeSubClass']) | ||||
|         self.apb.build_class_pages(data, self.project) | ||||
|         clsfile = self.base.join('api/main.SomeClass.html') | ||||
|  | @ -173,8 +176,7 @@ class TestApiPageBuilder(AbstractBuilderTest): | |||
|         _checkhtml(html) | ||||
| 
 | ||||
|     def test_build_class_pages_instance(self): | ||||
|         data = self.apb.prepare_class_pages(self.namespace_tree, | ||||
|                                             ['main.SomeClass', | ||||
|         data = self.apb.prepare_class_pages(['main.SomeClass', | ||||
|                                              'main.SomeSubClass', | ||||
|                                              'main.SomeInstance']) | ||||
|         self.apb.build_class_pages(data, self.project) | ||||
|  | @ -187,8 +189,7 @@ class TestApiPageBuilder(AbstractBuilderTest): | |||
|         ]) | ||||
| 
 | ||||
|     def test_build_class_pages_nav_links(self): | ||||
|         data = self.apb.prepare_class_pages(self.namespace_tree, | ||||
|                                             ['main.SomeSubClass', | ||||
|         data = self.apb.prepare_class_pages(['main.SomeSubClass', | ||||
|                                              'main.SomeClass']) | ||||
|         # fake some stuff that would be built from other methods | ||||
|         self.linker.set_link('', 'api/index.html') | ||||
|  | @ -212,8 +213,7 @@ class TestApiPageBuilder(AbstractBuilderTest): | |||
|         _checkhtml(html) | ||||
| 
 | ||||
|     def test_build_class_pages_base_link(self): | ||||
|         data = self.apb.prepare_class_pages(self.namespace_tree, | ||||
|                                             ['main.SomeSubClass', | ||||
|         data = self.apb.prepare_class_pages(['main.SomeSubClass', | ||||
|                                              'main.SomeClass']) | ||||
|         self.apb.build_class_pages(data, self.project) | ||||
|         clsfile = self.base.join('api/main.SomeSubClass.html') | ||||
|  | @ -227,8 +227,7 @@ class TestApiPageBuilder(AbstractBuilderTest): | |||
|         _checkhtml(html) | ||||
| 
 | ||||
|     def test_source_links(self): | ||||
|         data = self.apb.prepare_class_pages(self.namespace_tree, | ||||
|                                             ['main.SomeSubClass', | ||||
|         data = self.apb.prepare_class_pages(['main.SomeSubClass', | ||||
|                                              'main.SomeClass']) | ||||
|         sourcedata = self.spb.prepare_pages(self.fs_root) | ||||
|         self.apb.build_class_pages(data, self.project) | ||||
|  | @ -238,7 +237,7 @@ class TestApiPageBuilder(AbstractBuilderTest): | |||
|         _checkhtml(funchtml) | ||||
| 
 | ||||
|     def test_build_namespace_pages(self): | ||||
|         data = self.apb.prepare_namespace_pages(self.namespace_tree) | ||||
|         data = self.apb.prepare_namespace_pages() | ||||
|         self.apb.build_namespace_pages(data, self.project) | ||||
|         mainfile = self.base.join('api/main.html') | ||||
|         assert mainfile.check() | ||||
|  | @ -258,7 +257,7 @@ class TestApiPageBuilder(AbstractBuilderTest): | |||
|         _checkhtml(otherhtml) | ||||
| 
 | ||||
|     def test_build_namespace_pages_index(self): | ||||
|         data = self.apb.prepare_namespace_pages(self.namespace_tree) | ||||
|         data = self.apb.prepare_namespace_pages() | ||||
|         self.apb.build_namespace_pages(data, self.project) | ||||
|         pkgfile = self.base.join('api/index.html') | ||||
|         assert pkgfile.check() | ||||
|  | @ -267,7 +266,7 @@ class TestApiPageBuilder(AbstractBuilderTest): | |||
|         _checkhtml(html) | ||||
| 
 | ||||
|     def test_build_namespace_pages_subnamespace(self): | ||||
|         data = self.apb.prepare_namespace_pages(self.namespace_tree) | ||||
|         data = self.apb.prepare_namespace_pages() | ||||
|         self.apb.build_namespace_pages(data, self.project) | ||||
|         subfile = self.base.join('api/main.sub.html') | ||||
|         assert subfile.check() | ||||
|  | @ -275,8 +274,7 @@ class TestApiPageBuilder(AbstractBuilderTest): | |||
|         _checkhtml(html) | ||||
| 
 | ||||
|     def test_build_function_api_pages_nav(self): | ||||
|         data = self.apb.prepare_function_pages(self.namespace_tree, | ||||
|                                                    ['main.sub.func']) | ||||
|         data = self.apb.prepare_function_pages(['main.sub.func']) | ||||
|         self.linker.set_link('', 'api/index.html') | ||||
|         self.linker.set_link('main', 'api/main.html') | ||||
|         self.linker.set_link('main.sub', 'api/main.sub.html') | ||||
|  | @ -293,22 +291,30 @@ class TestApiPageBuilder(AbstractBuilderTest): | |||
|         _checkhtml(html) | ||||
| 
 | ||||
|     def test_build_function_navigation(self): | ||||
|         self.apb.prepare_namespace_pages(self.namespace_tree) | ||||
|         self.apb.prepare_function_pages(self.namespace_tree, ['main.sub.func']) | ||||
|         nav = self.apb.build_navigation('main.sub', ['main.sub.func'], | ||||
|                                         'main.sub.func') | ||||
|         self.apb.prepare_namespace_pages() | ||||
|         self.apb.prepare_function_pages(['main.sub.func']) | ||||
|         self.apb.prepare_class_pages(['main.SomeClass', | ||||
|                                              'main.SomeSubClass', | ||||
|                                              'main.SomeInstance']) | ||||
|         nav = self.apb.build_navigation('main.sub.func', False) | ||||
|         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/main.html">main</a></div>' | ||||
|                 u'<div>\xa0\xa0\xa0\xa0' | ||||
|         assert (u'<div class="selected"><a href="api/index.html">pkg</a></div>' | ||||
|                 u'<div class="selected">\xa0\xa0<a href="api/main.html">main</a></div>' | ||||
|                 u'<div>\xa0\xa0\xa0\xa0<a href="api/main.SomeClass.html">' | ||||
|                     u'SomeClass</a></div>' | ||||
|                 u'<div>\xa0\xa0\xa0\xa0<a href="api/main.SomeInstance.html">' | ||||
|                     u'SomeInstance</a></div>' | ||||
|                 u'<div>\xa0\xa0\xa0\xa0<a href="api/main.SomeSubClass.html">' | ||||
|                     u'SomeSubClass</a></div>' | ||||
|                 u'<div class="selected">\xa0\xa0\xa0\xa0' | ||||
|                     u'<a href="api/main.sub.html">sub</a></div>' | ||||
|                 u'<div class="selected">\xa0\xa0\xa0\xa0\xa0\xa0' | ||||
|                     u'<a href="api/main.sub.func.html">func</a></div>' | ||||
|         ) in html | ||||
| 
 | ||||
|     def test_build_root_namespace_view(self): | ||||
|         data = self.apb.prepare_namespace_pages(self.namespace_tree) | ||||
|         data = self.apb.prepare_namespace_pages() | ||||
|         self.apb.build_namespace_pages(data, self.project) | ||||
|         rootfile = self.base.join('api/index.html') | ||||
|         assert rootfile.check() | ||||
|  | @ -332,7 +338,6 @@ class TestSourcePageBuilder(AbstractBuilderTest): | |||
|         print html | ||||
|         run_string_sequence_test(html, [ | ||||
|             'href="../../style.css"', | ||||
|             '<a href="../index.html">root</a>', | ||||
|             '<a href="index.html">pkg</a>', | ||||
|             '<a href="someclass.py.html">someclass.py</a>', | ||||
|             '<a href="somesubclass.py.html">somesubclass.py</a>', | ||||
|  | @ -347,7 +352,6 @@ class TestSourcePageBuilder(AbstractBuilderTest): | |||
|         print html | ||||
|         run_string_sequence_test(html, [ | ||||
|             'href="../../style.css"', | ||||
|             '<a href="../index.html">root</a>', | ||||
|             '<a href="index.html">pkg</a>', | ||||
|             '<a href="func.py.html">func.py</a>', | ||||
|             '<a href="someclass.py.html">someclass.py</a>', | ||||
|  | @ -362,7 +366,6 @@ class TestSourcePageBuilder(AbstractBuilderTest): | |||
|         html = nav.unicode(indent=0) | ||||
|         print html.encode('UTF-8') | ||||
|         run_string_sequence_test(html, [ | ||||
|             'href="source/index.html">root', | ||||
|             'href="source/pkg/index.html">pkg', | ||||
|             'href="source/pkg/func.py.html">func.py', | ||||
|             'href="source/pkg/someclass.py.html">someclass.py', | ||||
|  |  | |||
|  | @ -4,6 +4,7 @@ | |||
| """ | ||||
| 
 | ||||
| import py | ||||
| from py.__.apigen import apigen | ||||
| 
 | ||||
| def setup_fs_project(): | ||||
|     temp = py.test.ensuretemp('apigen_functional') | ||||
|  | @ -70,6 +71,13 @@ def setup_fs_project(): | |||
|     """)) | ||||
|     return temp, 'pkg' | ||||
| 
 | ||||
| def test_get_documentable_items(): | ||||
|     fs_root, package_name = setup_fs_project() | ||||
|     documentable = apigen.get_documentable_items(fs_root.join(package_name)) | ||||
|     assert documentable.__package__.exportdefs.keys() == [ | ||||
|         'main.sub.func', 'main.func', 'main.SomeTestSubClass', | ||||
|         'main.SomeTestClass'] | ||||
| 
 | ||||
| def test_apigen_functional(): | ||||
|     fs_root, package_name = setup_fs_project() | ||||
|     tempdir = py.test.ensuretemp('test_apigen_functional_results') | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue