Skip to content

Commit

Permalink
Fixed a couple functional tests.
Browse files Browse the repository at this point in the history
Tried to remove the service terminology from the code as much as 
possible.
  • Loading branch information
strichter committed Jan 12, 2005
1 parent c959b33 commit 604ffed
Show file tree
Hide file tree
Showing 5 changed files with 550 additions and 6 deletions.
113 changes: 113 additions & 0 deletions ifacemodule/__init__.py
@@ -0,0 +1,113 @@
##############################################################################
#
# Copyright (c) 2004 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Interface Documentation Module
The interface documentation module retrieves its information from the
site manager. Therefore, currently there are no unregsitered interfaces
listed in the documentation. This might be good, since unregistered interfaces
are usually private and not of interest to a general developer.
$Id$
"""
__docformat__ = 'restructuredtext'

from zope.app import zapi
from zope.interface import implements
from zope.app.apidoc.interfaces import IDocumentationModule
from zope.app.apidoc.utilities import ReadContainerBase
from zope.app.location import LocationProxy
from zope.app.component.interface \
import queryInterface, searchInterfaceUtilities
from zope.app.i18n import ZopeMessageIDFactory as _

class IInterfaceModule(IDocumentationModule):
"""Interface API Documentation Module
This is a marker interface, so that we can write adapters for objects
implementing this interface.
"""

class InterfaceModule(ReadContainerBase):
r"""Represent the Documentation of all Interfaces.
This documentation is implemented using a simple `IReadContainer`. The
items of the container are all the interfaces listed in the closest
site manager and above.
Demonstration::
>>> module = InterfaceModule()
Lookup an interface that is registered.
>>> module.get('IInterfaceModule').getName()
'IInterfaceModule'
>>> id = 'zope.app.apidoc.interfaces.IDocumentationModule'
>>> module.get(id).getName()
'IDocumentationModule'
Here we find an interface that is not in the site manager, but exists.
>>> module.get('zope.app.content.interfaces.IContentType').getName()
'IContentType'
>>> print '\n'.join([id for id, iface in module.items()])
IInterfaceModule
zope.app.apidoc.interfaces.IDocumentationModule
"""

implements(IInterfaceModule)

# See zope.app.apidoc.interfaces.IDocumentationModule
title = _('Interfaces')

# See zope.app.apidoc.interfaces.IDocumentationModule
description = _("""
All used and important interfaces are registered through the site
manager. While it would be possible to just list all attributes, it is
hard on the user to read such an overfull list. Therefore, interfaces that
have partial common module paths are bound together.
The documentation of an interface also provides a wide variety of
information, including of course the declared attributes/fields and
methods, but also available adapters, and utilities that provide
this interface.
""")

def get(self, key, default=None):
"""See zope.app.interfaces.container.IReadContainer"""
iface = queryInterface(key, default)
if iface is default:
# Yeah, we find more items than we claim to have! This way we can
# handle all interfaces using this module. :-)
parts = key.split('.')
try:
mod = __import__('.'.join(parts[:-1]), {}, {}, ('*',))
except ImportError:
iface = default
else:
iface = getattr(mod, parts[-1], default)

if not iface is default:
iface = LocationProxy(iface, self, key)

return iface

def items(self):
"""See zope.app.interfaces.container.IReadContainer"""
items = list(searchInterfaceUtilities(self))
items.sort()
items = [(i[0], LocationProxy(i[1], self, i[0])) for i in items]
return items
179 changes: 179 additions & 0 deletions ifacemodule/menu.py
@@ -0,0 +1,179 @@
##############################################################################
#
# Copyright (c) 2004 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Interface Module Browser Menu (Tree)
A list of interfaces from the global site manager is pretty much unmanagable and
is very confusing. Therefore it is nice to split the path of the interface, so
that we get a deeper tree with nodes having shorter, manageable names.
$Id$
"""
__docformat__ = 'restructuredtext'

from zope.interface import implements
from zope.security.proxy import removeSecurityProxy

from zope.app import zapi
from zope.app.location.interfaces import ILocation
from zope.app.location import LocationProxy
from zope.app.tree.interfaces import IChildObjects

from zope.app.apidoc.ifacemodule import IInterfaceModule
from zope.app.apidoc.utilities import ReadContainerBase

class IModule(ILocation):
"""Represents some module
Marker interface, so that we can register an adapter for it."""


class Module(ReadContainerBase):
r"""Represents a Python module
Examples: zope, zope.app, zope.app.interfaces
However, we usually use it only for the last case.
Usage::
>>> from zope.app.apidoc.ifacemodule import InterfaceModule
>>> module = Module(InterfaceModule(), 'zope.app')
>>> module.get('apidoc.interfaces.IDocumentationModule').getName()
'IDocumentationModule'
>>> module.get(
... 'zope.app.apidoc.interfaces.IDocumentationModule') is None
True
>>> print '\n'.join([id for id, iface in module.items()])
zope.app.apidoc.interfaces.IDocumentationModule
"""

implements(IModule)

def __init__(self, parent, name):
self.__parent__ = parent
self.__name__ = name

def get(self, key, default=None):
name = self.__name__ + '.' + key
return self.__parent__.get(name, default)

def items(self):
parent = self.__parent__
items = []
for key in parent.keys():
if key.startswith(self.__name__):
items.append((key, LocationProxy(parent[key], self, key)))
return items


class InterfaceModuleChildObjects(object):
r"""Module Adapter for Static Tree
This adapter is used when building a static tree for the browser.
Functionality::
>>> from zope.app.apidoc.ifacemodule import InterfaceModule
>>> from zope.app.apidoc.ifacemodule import tests
>>> module = InterfaceModule()
>>> module = tests.rootLocation(module, 'Interface')
>>> adapter = InterfaceModuleChildObjects(module)
>>> adapter.hasChildren()
True
>>> print '\n'.join([c.__name__ for c in adapter.getChildObjects()])
IInterfaceModule
zope.app.apidoc.interfaces
"""

implements(IChildObjects)
__used_for__ = IInterfaceModule

def __init__(self, context):
self.context = context

def hasChildren(self):
"""See zope.app.tree.interfaces.IChildObject"""
return bool(len(self.context))

def getChildObjects(self):
"""See zope.app.tree.interfaces.IChildObject"""
objects = {}
names = removeSecurityProxy(self.context.keys())
names.sort()
for name in names:
# Split these long names and make part of the module path separate
# entries. Currently we only split by the term '.interfaces', but
# a more sophisticated algorithm could be developed.
iface_loc = name.find('.interfaces')
if iface_loc == -1:
objects[name] = LocationProxy(self.context[name],
self.context, name)
else:
module_name = name[:iface_loc+11]
objects[module_name] = Module(self.context, module_name)
items = objects.items()
items.sort()
return [x[1] for x in items]


class Menu(object):
"""Menu View Helper Class
A class that helps building the menu. The menu_macros expects the menu view
class to have the `getMenuTitle(node)` and `getMenuLink(node)` methods
implemented. `node` is a `zope.app.tree.node.Node` instance.
Examples::
>>> from zope.app.apidoc.ifacemodule import InterfaceModule
>>> from zope.app.apidoc.ifacemodule.tests import Root
>>> from zope.app.tree.node import Node
>>> ifacemod = InterfaceModule()
>>> ifacemod.__parent__ = Root()
>>> ifacemod.__name__ = 'Interfaces'
>>> mod = Module(ifacemod, 'zope.app.apidoc.interfaces')
>>> menu = Menu()
>>> node = Node(mod.get('IDocumentationModule'))
>>> menu.getMenuTitle(node)
'zope.app.apidoc.interfaces.IDocumentationModule'
>>> values = mod.values()
>>> values.sort()
>>> node = Node(values[0])
>>> menu.getMenuTitle(node)
u'IDocumentationModule'
>>> menu.getMenuLink(node)
u'./zope.app.apidoc.interfaces.IDocumentationModule/apiindex.html'
"""

def getMenuTitle(self, node):
"""Return the title of the node that is displayed in the menu."""
if zapi.isinstance(node.context.__parent__, Module):
parent = node.context.__parent__
return zapi.name(node.context).replace(zapi.name(parent)+'.', '')
return zapi.name(node.context)

def getMenuLink(self, node):
"""Return the HTML link of the node that is displayed in the menu."""
if zapi.isinstance(node.context, Module):
return None
return './' + zapi.name(node.context) + '/apiindex.html'
8 changes: 4 additions & 4 deletions utilitymodule/__init__.py
Expand Up @@ -108,7 +108,7 @@ class UtilityModule(ReadContainerBase):
This documentation is implemented using a simple `IReadContainer`. The
items of the container are all factories listed in the closest
factory service and above.
site manager and above.
Demonstration::
Expand All @@ -131,14 +131,14 @@ class UtilityModule(ReadContainerBase):

# See zope.app.apidoc.interfaces.IDocumentationModule
description = _("""
Utilities are also nicely registered in a service, so that it is easy to
create a listing of available utilities. A utility is identified by the
Utilities are also nicely registered in a site manager, so that it is easy
to create a listing of available utilities. A utility is identified by the
providing interface and a name, which can be empty. The menu provides you
with a list of interfaces that utilities provide and as sub-items the
names of the various implementations.
Again, the documentation of a utility lists all the attributes/fields and
methods the utility provides and provides a link to the implementation.
methods the utility provides and provides a link to the implementation.
""")

def get(self, key, default=None):
Expand Down
4 changes: 2 additions & 2 deletions viewmodule/browser.py
Expand Up @@ -67,7 +67,7 @@ def getPresentationTypes(self):

def getInterfaceIds(self):
"""Get a list of the ids of all interfaces registered with the
interface service.
site manager.
Example::
Expand Down Expand Up @@ -244,7 +244,7 @@ def __init__(self, context, request):
self.show_all = request.has_key('all')

sm = zapi.getSiteManager()
# This is okay here, since we only read from the service. Once
# This is okay here, since we only read from the site manager. Once
# registration objects have sensible security declarations, we can
# remove that call.
from zope.proxy import removeAllProxies
Expand Down

0 comments on commit 604ffed

Please sign in to comment.