======================================
Module Menu and ZCML Directive Details
======================================

This document provides an overview of all browser-presentation related
objects.

`getAllTextOfInterface(iface)`
------------------------------

Get all searchable text from an interface

  >>> import zope.interface
  >>> import zope.schema
  >>> class IFoo(zope.interface.Interface):
  ...     '''foo'''
  ...
  ...     def bar(self):
  ...         '''bar'''
  ...
  ...     blah = zope.interface.Attribute('blah', 'blah')
  ...
  ...     field = zope.schema.Field(
  ...         title = u'title', description = u'description')

Now get the text. Note that there is no particular order during the text
collection.

  >>> from zope.app.apidoc.ifacemodule.menu import getAllTextOfInterface
  >>> text = getAllTextOfInterface(IFoo)
  >>> u'foo' in text
  True
  >>> u'bar' in text
  True
  >>> u'blah' in text
  True
  >>> u'field' in text
  True
  >>> u'title' in text
  True
  >>> u'description' in text
  True


`Menu` class
------------

This is the menu class for the Interface Documentation Module.

The menu allows one to look for interfaces by full-text search or partial
names. The `findInterfaces()` function provides a simple search mechanism.

Before we can test the method, let's create a `Menu` instance:

  >>> from zope.interface.interfaces import IElement, IAttribute

  >>> from zope.app.apidoc.ifacemodule.menu import Menu
  >>> menu = Menu()
  >>> menu.context = {'IElement': IElement, 'IAttribute': IAttribute}
  >>> menu.request = {'name_only': 'on', 'search_str': ''}

Now let's see how successful our searches are:

  >>> menu.request['search_str'] = 'Elem'
  >>> pprint(menu.findInterfaces())
  [{'name': 'IElement',
    'url': './IElement/index.html'}]

  >>> menu.request['search_str'] = 'I'
  >>> pprint(menu.findInterfaces())
  [{'name': 'IAttribute',
    'url': './IAttribute/index.html'},
   {'name': 'IElement',
    'url': './IElement/index.html'}]

Now using the full text search:

  >>> del menu.request['name_only']

  >>> menu.request['search_str'] = 'object'
  >>> pprint(menu.findInterfaces())
  [{'name': 'IAttribute',
    'url': './IAttribute/index.html'},
   {'name': 'IElement',
    'url': './IElement/index.html'}]

  >>> menu.request['search_str'] = 'Stores'
  >>> pprint(menu.findInterfaces())
  [{'name': 'IAttribute',
    'url': './IAttribute/index.html'}]


`InterfaceDetails` class
------------------------

This view provides many details about an interface. Most methods of the class
actually use the public inspection API.

Before we can test the view, we need to create an interesting setup, so that
the view can provide some useful data. Let's start by defining a complex
interface:

  >>> class IFoo(zope.interface.Interface):
  ...     """This is the Foo interface
  ...
  ...     More description here...
  ...     """
  ...     foo = zope.interface.Attribute('This is foo.')
  ...     bar = zope.interface.Attribute('This is bar.')
  ...
  ...     title = zope.schema.TextLine(
  ...         description=u'Title',
  ...         required=True,
  ...         default=u'Foo')
  ...
  ...     description = zope.schema.Text(
  ...         description=u'Desc',
  ...         required=False,
  ...         default=u'Foo.')
  ...
  ...     def blah():
  ...         """This is blah."""
  ...
  ...     def get(key, default=None):
  ...         """This is get."""

Let's now create another interface `IBar` and make `Foo` an adapter from
`IBar` to `IFoo`:

  >>> class IBar(zope.interface.Interface):
  ...     pass

  >>> class Foo(object):
  ...     zope.interface.implements(IFoo)

  >>> from zope.app.testing import ztapi
  >>> ztapi.provideAdapter(IBar, IFoo, Foo)

  >>> from zope.app.apidoc.classregistry import classRegistry
  >>> classRegistry['__builtin__.Foo'] = Foo

Let's also register a factory for `Foo`

  >>> from zope.component.interfaces import IFactory
  >>> from zope.component.factory import Factory
  >>> ztapi.provideUtility(IFactory, Factory(Foo, title='Foo Factory'),
  ...                      'FooFactory')

and a utility providing `IFoo`:

  >>> ztapi.provideUtility(IFoo, Foo(), 'The Foo')

Now that the initial setup is done, we can create an interface that is located
in the interface documentation module

  >>> from zope.app.apidoc.ifacemodule.ifacemodule import InterfaceModule
  >>> ifacemodule = InterfaceModule()

  >>> from zope.app.apidoc.tests import Root
  >>> ifacemodule.__parent__ = Root()
  >>> ifacemodule.__name__ = 'Interfaces'

  >>> from zope.location import LocationProxy
  >>> iface = LocationProxy(IFoo, ifacemodule, 'IFoo')

and finally the details view:

  >>> from zope.publisher.browser import TestRequest
  >>> from zope.app.apidoc.ifacemodule.browser import InterfaceDetails
  >>> details = InterfaceDetails(iface, TestRequest())


`getId()`
---------

Return the id of the field as it is defined for the interface
utility.

  >>> details.getId()
  'IFoo'

`getDoc()`
----------

Return the main documentation string of the interface.

  >>> details.getDoc()[:32]
  u'<p>This is the Foo interface</p>'


`getBases()`
------------

Get all bases of this class

  >>> details.getBases()
  ['zope.interface.Interface']


`getTypes()`
------------

Return a list of interface types that are specified for this interface.

Initially we do not have any types

  >>> details.getTypes()
  []

but when I create and assign a type to the interface

  >>> class IMyType(zope.interface.interfaces.IInterface):
  ...     pass

  >>> zope.interface.directlyProvides(IFoo, IMyType)

we get a result:

  >>> pprint(details.getTypes())
  [{'name': 'IMyType',
    'path': '__builtin__.IMyType'}]


`getAttributes()`
-----------------

Return a list of attributes in the order they were specified.

  >>> pprint(details.getAttributes())
  [{'doc': u'<p>This is bar.</p>\n',
    'name': 'bar'},
   {'doc': u'<p>This is foo.</p>\n',
    'name': 'foo'}]


`getMethods()`
--------------

Return a list of methods in the order they were specified.

  >>> pprint(details.getMethods())
  [{'doc': u'<p>This is blah.</p>\n',
    'name': 'blah',
    'signature': '()'},
   {'doc': u'<p>This is get.</p>\n',
    'name': 'get',
    'signature': '(key, default=None)'}]


`getFields()`
-------------

Return a list of fields in required + alphabetical order.

The required attributes are listed first, then the optional attributes.

  >>> pprint(details.getFields())
  [{'class': {'name': 'TextLine',
              'path': 'zope/schema/_bootstrapfields/TextLine'},
    'default': "u'Foo'",
    'description': u'<p>Title</p>\n',
    'iface': {'id': 'zope.schema.interfaces.ITextLine',
              'name': 'ITextLine'},
    'name': 'title',
    'required': True,
    'required_string': u'required',
    'title': u''},
   {'class': {'name': 'Text',
              'path': 'zope/schema/_bootstrapfields/Text'},
    'default': "u'Foo.'",
    'description': u'<p>Desc</p>\n',
    'iface': {'id': 'zope.schema.interfaces.IText',
              'name': 'IText'},
    'name': 'description',
    'required': False,
    'required_string': u'optional',
    'title': u''}]

`getSpecificRequiredAdapters()`
-------------------------------

Get adapters where this interface is required.

  >>> pprint(details.getSpecificRequiredAdapters())
  []

`getExtendedRequiredAdapters()`
-------------------------------

Get adapters where this interface is required.

  >>> pprint(details.getExtendedRequiredAdapters())
  []

Note that this includes all interfaces registered for
interface.Interface.


`getGenericRequiredAdapters()`
------------------------------

Get adapters where this interface is required.

  >>> pprint(sorted(details.getGenericRequiredAdapters()))
  [{'doc': u'',
    'factory': 'None.append',
    'factory_url': None,
    'name': u'',
    'provided': None,
    'required': [{'module': 'zope.interface',
                  'name': 'Interface'}],
    'zcml': None},
   {'doc': u'',
    'factory': 'zope.location.traversing.LocationPhysicallyLocatable',
    'factory_url': 'zope/location/traversing/LocationPhysicallyLocatable',
    'name': u'',
    'provided': {'module': 'zope.traversing.interfaces',
                 'name': 'IPhysicallyLocatable'},
    'required': [{'module': 'zope.interface',
                  'name': 'Interface'}],
    'zcml': None},
   {'doc': u'',
    'factory': 'zope.traversing.adapters.DefaultTraversable',
    'factory_url': 'zope/traversing/adapters/DefaultTraversable',
    'name': u'',
    'provided': {'module': 'zope.traversing.interfaces',
                 'name': 'ITraversable'},
    'required': [{'module': 'zope.interface',
                  'name': 'Interface'}],
    'zcml': None},
   {'doc': u'',
    'factory': 'zope.traversing.adapters.Traverser',
    'factory_url': 'zope/traversing/adapters/Traverser',
    'name': u'',
    'provided': {'module': 'zope.traversing.interfaces',
                 'name': 'ITraverser'},
    'required': [{'module': 'zope.interface',
                  'name': 'Interface'}],
    'zcml': None},
   {'doc': u'',
    'factory': 'zope.traversing.namespace.etc',
    'factory_url': 'zope/traversing/namespace/etc',
    'name': u'etc',
    'provided': {'module': 'zope.traversing.interfaces',
                 'name': 'ITraversable'},
    'required': [{'module': 'zope.interface',
                  'name': 'Interface'}],
    'zcml': None},
   {'doc': u'',
    'factory': 'zope.traversing.namespace.etc',
    'factory_url': 'zope/traversing/namespace/etc',
    'name': u'etc',
    'provided': {'module': 'zope.traversing.interfaces',
                 'name': 'ITraversable'},
    'required': [{'module': 'zope.interface',
                  'name': 'Interface'},
                 {'module': 'zope.interface',
                  'name': 'Interface'}],
    'zcml': None},
   {'doc': u'',
    'factory': 'zope.traversing.namespace.etc',
    'factory_url': 'zope/traversing/namespace/etc',
    'name': u'etc',
    'provided': {'module': 'zope.traversing.interfaces',
                 'name': 'ITraversable'},
    'required': [{'module': 'zope.interface',
                  'name': 'Interface'},
                 {'module': 'zope.interface',
                  'name': 'Interface'}],
    'zcml': None},
   {'doc': u'',
    'factory': 'zope.traversing.namespace.etc',
    'factory_url': 'zope/traversing/namespace/etc',
    'name': u'etc',
    'provided': {'module': 'zope.traversing.interfaces',
                 'name': 'ITraversable'},
    'required': [{'module': 'zope.interface',
                  'name': 'Interface'},
                 {'module': 'zope.interface',
                  'name': 'Interface'}],
    'zcml': None},
   {'doc': u'',
    'factory': 'zope.traversing.namespace.etc',
    'factory_url': 'zope/traversing/namespace/etc',
    'name': u'etc',
    'provided': {'module': 'zope.traversing.interfaces',
                 'name': 'ITraversable'},
    'required': [{'module': 'zope.interface',
                  'name': 'Interface'},
                 {'module': 'zope.interface',
                  'name': 'Interface'}],
    'zcml': None}]


`getProvidedAdapters()`
-----------------------

Get adapters where this interface is provided.

  >>> pprint(details.getProvidedAdapters())
  [{'doc': u'',
    'factory': '__builtin__.Foo',
    'factory_url': None,
    'name': u'',
    'provided': {'module': '__builtin__', 'name': 'IFoo'},
    'required': [{'module': '__builtin__', 'name': 'IBar'}],
    'zcml': None}]


`getClasses()`
---------------

Get the classes that implement this interface.

  >>> pprint(details.getClasses())
  [{'path': '__builtin__.Foo',
    'url': '__builtin__/Foo'}]

`getFactories()`
----------------

Return the factories, who will provide objects implementing this
interface.

  >>> pprint(details.getFactories())
  [{'description': u'',
    'name': u'FooFactory',
    'title': 'Foo Factory',
    'url': None}]

`getUtilities()`
----------------

Return all utilities that provide this interface.

  >>> pprint(details.getUtilities())
  [{'iface_id': '__builtin__.IFoo',
    'name': u'The Foo',
    'path': '__builtin__.Foo',
    'url': None,
    'url_name': 'VGhlIEZvbw=='}]
