[Checkins] SVN: grok/trunk/ - added application object

Christian Theune ct at gocept.com
Wed Feb 7 01:20:15 EST 2007


Log message for revision 72409:
   - added application object
   - added *very* minimal admin ui
  

Changed:
  D   grok/trunk/grokwiki/src/grokwiki/configure.zcml
  U   grok/trunk/grokwiki/src/grokwiki/wiki.py
  U   grok/trunk/ldapaddressbook/src/ldapaddressbook/addressbook.py
  U   grok/trunk/src/grok/__init__.py
  A   grok/trunk/src/grok/admin/
  A   grok/trunk/src/grok/admin/README.txt
  A   grok/trunk/src/grok/admin/__init__.py
  A   grok/trunk/src/grok/admin/configure.zcml
  A   grok/trunk/src/grok/admin/manage.pt
  A   grok/trunk/src/grok/admin/view.py
  U   grok/trunk/src/grok/components.py
  U   grok/trunk/src/grok/configure.zcml
  A   grok/trunk/src/grok/ftests/admin/
  A   grok/trunk/src/grok/ftests/admin/__init__.py
  A   grok/trunk/src/grok/ftests/admin/admin.py
  U   grok/trunk/src/grok/ftests/form/templateform.py
  U   grok/trunk/src/grok/ftests/test_grok_functional.py
  U   grok/trunk/src/grok/interfaces.py
  U   grok/trunk/src/grok/meta.py
  A   grok/trunk/src/grok/tests/application/
  A   grok/trunk/src/grok/tests/application/__init__.py
  A   grok/trunk/src/grok/tests/application/application.py
  U   grok/trunk/src/grok/tests/test_grok.py

-=-
Deleted: grok/trunk/grokwiki/src/grokwiki/configure.zcml
===================================================================
--- grok/trunk/grokwiki/src/grokwiki/configure.zcml	2007-02-06 23:19:06 UTC (rev 72408)
+++ grok/trunk/grokwiki/src/grokwiki/configure.zcml	2007-02-07 06:20:13 UTC (rev 72409)
@@ -1,15 +0,0 @@
-<configure
-    xmlns="http://namespaces.zope.org/zope"
-    xmlns:browser="http://namespaces.zope.org/browser"
-    xmlns:grok="http://namespaces.zope.org/grok"
-    i18n_domain="grok"
-    >
-    <grok:grok package="."/>
-
-    <browser:addMenuItem
-        class=".wiki.Wiki"
-        title="GROK WIKI"
-        description="GROK NOW WIKI"
-        permission="zope.ManageContent"
-        />
-</configure>

Modified: grok/trunk/grokwiki/src/grokwiki/wiki.py
===================================================================
--- grok/trunk/grokwiki/src/grokwiki/wiki.py	2007-02-06 23:19:06 UTC (rev 72408)
+++ grok/trunk/grokwiki/src/grokwiki/wiki.py	2007-02-07 06:20:13 UTC (rev 72409)
@@ -17,7 +17,7 @@
 import grok
 import grokwiki.page
 
-class Wiki(grok.Container):
+class Wiki(grok.Application):
     """This is our wiki application wich contains all wiki pages."""
 
 class Index(grok.View):

Modified: grok/trunk/ldapaddressbook/src/ldapaddressbook/addressbook.py
===================================================================
--- grok/trunk/ldapaddressbook/src/ldapaddressbook/addressbook.py	2007-02-06 23:19:06 UTC (rev 72408)
+++ grok/trunk/ldapaddressbook/src/ldapaddressbook/addressbook.py	2007-02-07 06:20:13 UTC (rev 72409)
@@ -30,7 +30,7 @@
 
 
 
-class AddressBook(grok.Model):
+class AddressBook(grok.Application):
 
     def traverse(self, name):
         contact = Contact(name)

Modified: grok/trunk/src/grok/__init__.py
===================================================================
--- grok/trunk/src/grok/__init__.py	2007-02-06 23:19:06 UTC (rev 72408)
+++ grok/trunk/src/grok/__init__.py	2007-02-07 06:20:13 UTC (rev 72409)
@@ -33,6 +33,7 @@
 from grok.components import Model, Adapter, MultiAdapter, View, XMLRPC
 from grok.components import PageTemplate, PageTemplateFile, Container, Traverser
 from grok.components import Site, GlobalUtility, LocalUtility, Annotation
+from grok.components import Application
 from grok.components import EditForm, DisplayForm, AddForm
 from grok.directive import (context, name, template, templatedir, provides,
                             baseclass, global_utility, local_utility,

Added: grok/trunk/src/grok/admin/README.txt
===================================================================
--- grok/trunk/src/grok/admin/README.txt	2007-02-06 23:19:06 UTC (rev 72408)
+++ grok/trunk/src/grok/admin/README.txt	2007-02-07 06:20:13 UTC (rev 72409)
@@ -0,0 +1,9 @@
+A basic grok admin UI.
+
+- Overview
+
+    - list of all instanciated applications (grouped by application?)
+
+    - "Add new application" form: drop down for selecting the application and
+      a field for the id.
+


Property changes on: grok/trunk/src/grok/admin/README.txt
___________________________________________________________________
Name: svn:keywords
   + Id Rev Date
Name: svn:eol-style
   + native

Added: grok/trunk/src/grok/admin/__init__.py
===================================================================
--- grok/trunk/src/grok/admin/__init__.py	2007-02-06 23:19:06 UTC (rev 72408)
+++ grok/trunk/src/grok/admin/__init__.py	2007-02-07 06:20:13 UTC (rev 72409)
@@ -0,0 +1 @@
+#make this a package


Property changes on: grok/trunk/src/grok/admin/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id Rev Date
Name: svn:eol-style
   + native

Added: grok/trunk/src/grok/admin/configure.zcml
===================================================================
--- grok/trunk/src/grok/admin/configure.zcml	2007-02-06 23:19:06 UTC (rev 72408)
+++ grok/trunk/src/grok/admin/configure.zcml	2007-02-07 06:20:13 UTC (rev 72409)
@@ -0,0 +1,19 @@
+<configure
+  xmlns="http://namespaces.zope.org/zope"
+  xmlns:browser="http://namespaces.zope.org/browser">
+
+  <browser:pages
+    for="zope.app.folder.interfaces.IRootFolder"
+    class=".view.Admin"
+    permission="zope.ManageApplication">
+    <browser:page
+      template="manage.pt"
+      name="index.html"
+      />
+    <browser:page
+      name="add"
+      attribute="add"
+      />
+  </browser:pages>
+
+</configure>


Property changes on: grok/trunk/src/grok/admin/configure.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: grok/trunk/src/grok/admin/manage.pt
===================================================================
--- grok/trunk/src/grok/admin/manage.pt	2007-02-06 23:19:06 UTC (rev 72408)
+++ grok/trunk/src/grok/admin/manage.pt	2007-02-07 06:20:13 UTC (rev 72409)
@@ -0,0 +1,40 @@
+<html>
+  <head>
+    <title>grok administration interface</title>
+  </head>
+
+  <body>
+    <h1>Installed applications</h1>
+
+    <ul>
+      <li tal:repeat="app context/values">
+        <a tal:attributes="href string:${context/@@absolute_url}/${app/__name__}">
+          <span tal:replace="app/__name__"/>
+          (<span tal:replace="app/__class__/__name__"/>)
+        </a>
+      </li>
+    </ul>
+
+    <form tal:attributes="action string:${context/@@absolute_url}/add">
+      <fieldset>
+        <legend>Add application</legend>
+
+        <p>
+          <label>Application: 
+            <select height="1" name="application"> 
+              <option tal:repeat="app view/applications" 
+                tal:attributes="value app" 
+                tal:content="app"
+                />
+            </select> 
+          </label>
+        </p>
+
+        <p><label>Name: <input type="text" name="name"/></label></p>
+
+        <p><input type="submit" value="Add"/></p>
+
+      </fieldset>
+    </form>
+  </body>
+</html>


Property changes on: grok/trunk/src/grok/admin/manage.pt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: grok/trunk/src/grok/admin/view.py
===================================================================
--- grok/trunk/src/grok/admin/view.py	2007-02-06 23:19:06 UTC (rev 72408)
+++ grok/trunk/src/grok/admin/view.py	2007-02-07 06:20:13 UTC (rev 72409)
@@ -0,0 +1,25 @@
+import zope.component
+import grok.interfaces
+
+from zope.app import zapi
+
+
+class Admin(object):
+
+    def __init__(self, context, request):
+        self.context = context
+        self.request = request
+
+    @property
+    def applications(self):
+        apps = zope.component.getAllUtilitiesRegisteredFor(
+            grok.interfaces.IApplication)
+        return ["%s.%s" % (x.__module__, x.__name__)
+                for x in apps]
+
+    def add(self, application, name):
+        app = zope.component.getUtility(grok.interfaces.IApplication,
+                                        name=application)
+        self.context[name] = app()
+        self.request.response.redirect(zapi.absoluteURL(self.context,
+                                                        self.request))


Property changes on: grok/trunk/src/grok/admin/view.py
___________________________________________________________________
Name: svn:keywords
   + Id Rev Date
Name: svn:eol-style
   + native

Modified: grok/trunk/src/grok/components.py
===================================================================
--- grok/trunk/src/grok/components.py	2007-02-06 23:19:06 UTC (rev 72408)
+++ grok/trunk/src/grok/components.py	2007-02-07 06:20:13 UTC (rev 72409)
@@ -111,6 +111,10 @@
     pass
 
 
+class Application(Site, Container):
+    """A top-level application object."""
+
+
 class Adapter(object):
 
     def __init__(self, context):

Modified: grok/trunk/src/grok/configure.zcml
===================================================================
--- grok/trunk/src/grok/configure.zcml	2007-02-06 23:19:06 UTC (rev 72408)
+++ grok/trunk/src/grok/configure.zcml	2007-02-07 06:20:13 UTC (rev 72409)
@@ -42,4 +42,6 @@
       priority="11"
       />
 
+  <include package=".admin"/>
+
 </configure>

Added: grok/trunk/src/grok/ftests/admin/__init__.py
===================================================================
--- grok/trunk/src/grok/ftests/admin/__init__.py	2007-02-06 23:19:06 UTC (rev 72408)
+++ grok/trunk/src/grok/ftests/admin/__init__.py	2007-02-07 06:20:13 UTC (rev 72409)
@@ -0,0 +1 @@
+# this is a package


Property changes on: grok/trunk/src/grok/ftests/admin/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id Rev Date
Name: svn:eol-style
   + native

Added: grok/trunk/src/grok/ftests/admin/admin.py
===================================================================
--- grok/trunk/src/grok/ftests/admin/admin.py	2007-02-06 23:19:06 UTC (rev 72408)
+++ grok/trunk/src/grok/ftests/admin/admin.py	2007-02-07 06:20:13 UTC (rev 72409)
@@ -0,0 +1,43 @@
+"""
+  >>> import grok
+  >>> grok.grok('grok.ftests.admin.admin')
+
+  >>> from zope.testbrowser.testing import Browser
+  >>> browser = Browser()
+  >>> browser.addHeader('Authorization', 'Basic mgr:mgrpw')
+  >>> browser.handleErrors = False
+  >>> browser.open("http://localhost/")
+  >>> print browser.contents
+  <html>
+  ...
+  <h1>Installed applications</h1>
+  ...
+  <legend>Add application</legend>
+  ...
+  >>> browser.getControl('Application').displayValue = ['grok.ftests.admin.admin.MammothManager']
+  >>> browser.getControl('Name').value = 'my-mammoth-manager'
+  >>> browser.getControl('Add').click()
+  >>> print browser.contents
+  <html>
+  ...
+  <li>
+    <a href="http://localhost/my-mammoth-manager">
+    my-mammoth-manager
+    (MammothManager)
+    </a>
+  </li>
+  ...
+  >>> browser.getLink('my-mammoth-manager').click()
+  >>> print browser.contents
+  Let's manage some mammoths!
+
+"""
+import grok
+
+class MammothManager(grok.Application):
+    pass
+
+class Index(grok.View):
+
+    def render(self):
+        return u"Let's manage some mammoths!"


Property changes on: grok/trunk/src/grok/ftests/admin/admin.py
___________________________________________________________________
Name: svn:keywords
   + Id Rev Date
Name: svn:eol-style
   + native

Modified: grok/trunk/src/grok/ftests/form/templateform.py
===================================================================
--- grok/trunk/src/grok/ftests/form/templateform.py	2007-02-06 23:19:06 UTC (rev 72408)
+++ grok/trunk/src/grok/ftests/form/templateform.py	2007-02-07 06:20:13 UTC (rev 72409)
@@ -45,7 +45,7 @@
 
 class Edit(grok.EditForm):
     pass
-    
+
 class Edit2(grok.EditForm):
     pass
 

Modified: grok/trunk/src/grok/ftests/test_grok_functional.py
===================================================================
--- grok/trunk/src/grok/ftests/test_grok_functional.py	2007-02-06 23:19:06 UTC (rev 72408)
+++ grok/trunk/src/grok/ftests/test_grok_functional.py	2007-02-07 06:20:13 UTC (rev 72409)
@@ -58,7 +58,7 @@
 def test_suite():
     suite = unittest.TestSuite()
     for name in ['view', 'static', 'xmlrpc', 'traversal', 'form', 'url',
-                 'security', 'utility', 'catalog']:
+                 'security', 'utility', 'catalog', 'admin']:
         suite.addTest(suiteFromPackage(name))
     return suite
 

Modified: grok/trunk/src/grok/interfaces.py
===================================================================
--- grok/trunk/src/grok/interfaces.py	2007-02-06 23:19:06 UTC (rev 72408)
+++ grok/trunk/src/grok/interfaces.py	2007-02-07 06:20:13 UTC (rev 72409)
@@ -26,6 +26,7 @@
                                 "(models).")
     Container = interface.Attribute("Base class for containers.")
     Site = interface.Attribute("Mixin class for sites.")
+    Application = interface.Attribute("Base class for applications.")
     Adapter = interface.Attribute("Base class for adapters.")
     MultiAdapter = interface.Attribute("Base class for multi-adapters.")
     Annotation = interface.Attribute("Base class for persistent annotations.")
@@ -37,7 +38,8 @@
     EditForm = interface.Attribute("Base class for edit forms.")
     DisplayForm = interface.Attribute("Base class for display forms.")
     AddForm = interface.Attribute("Base class for add forms.")
-    
+
+
 class IGrokErrors(interface.Interface):
 
     def GrokError(message, component):
@@ -47,6 +49,7 @@
     def GrokImportError(*args):
         """Error indicating a problem at import time."""
 
+
 class IGrokDirectives(interface.Interface):
 
     def implements(*interfaces):
@@ -91,7 +94,7 @@
         This means it won't be grokked, though if it's a possible context,
         it can still serve as a context.
         """
-        
+
     def global_utility(factory, provides=None, name=u''):
         """Register a global utility.
 
@@ -127,6 +130,7 @@
         grok.require can be used as a class-level directive or as a
         method decorator."""
 
+
 class IGrokDecorators(interface.Interface):
 
     def subscribe(*classes_or_interfaces):
@@ -139,6 +143,7 @@
     traverse = interface.Attribute("Specify a method to be used for "
                                    "traversing URL paths.")
 
+
 class IGrokEvents(interface.Interface):
 
     IObjectCreatedEvent = interface.Attribute("")
@@ -169,6 +174,7 @@
 
     ContainerModifiedEvent = interface.Attribute("")
 
+
 class IGrokAPI(IGrokBaseClasses, IGrokDirectives, IGrokDecorators,
                IGrokEvents, IGrokErrors):
 
@@ -197,11 +203,12 @@
     def AutoFields(context):
         """Return a list of fields for context autogenerated by grok.
         """
-        
+
     def action(label, actions=None, **options):
         """grok-specific action decorator.
         """
 
+
 class IGrokView(interface.Interface):
     """Grok views all provide this interface.
     """
@@ -221,3 +228,12 @@
         If both object and name arguments are supplied, construct
         URL to obj/name.
         """
+
+
+class IApplication(interface.Interface):
+    """Marker-interface for grok application factories.
+
+    Used to register applications as utilities to look them up and
+    provide a list of grokked applications.
+
+    """

Modified: grok/trunk/src/grok/meta.py
===================================================================
--- grok/trunk/src/grok/meta.py	2007-02-06 23:19:06 UTC (rev 72408)
+++ grok/trunk/src/grok/meta.py	2007-02-07 06:20:13 UTC (rev 72409)
@@ -26,14 +26,17 @@
 
     def register(self, context, name, factory, module_info, templates):
         for field in formlib.get_context_schema_fields(factory):
-            setattr(factory, field.__name__, field.default)       
+            setattr(factory, field.__name__, field.default)
 
+
 class ContainerGrokker(ModelGrokker):
     component_class = grok.Container
-    
+
+
 class LocalUtilityGrokker(ModelGrokker):
     component_class = grok.LocalUtility
-    
+
+
 class AdapterGrokker(grok.ClassGrokker):
     component_class = grok.Adapter
 
@@ -47,9 +50,10 @@
                                  provides=provides,
                                  name=name)
 
+
 class MultiAdapterGrokker(grok.ClassGrokker):
     component_class = grok.MultiAdapter
-    
+
     def register(self, context, name, factory, module_info, templates):
         provides = util.class_annotation(factory, 'grok.provides', None)
         if provides is None:
@@ -58,6 +62,7 @@
         name = util.class_annotation(factory, 'grok.name', '')
         component.provideAdapter(factory, provides=provides, name=name)
 
+
 class GlobalUtilityGrokker(grok.ClassGrokker):
     component_class = grok.GlobalUtility
 
@@ -68,6 +73,7 @@
         name = util.class_annotation(factory, 'grok.name', '')
         component.provideUtility(factory(), provides=provides, name=name)
 
+
 class XMLRPCGrokker(grok.ClassGrokker):
     component_class = grok.XMLRPC
 
@@ -111,6 +117,7 @@
                 checker = NamesChecker(['__call__'], permission)
             defineChecker(method_view, checker)
 
+
 class ViewGrokker(grok.ClassGrokker):
     component_class = grok.View
 
@@ -219,6 +226,7 @@
                                 'for XML-RPC methods.'
                                 % (method.__name__, factory), factory)
 
+
 class TraverserGrokker(grok.ClassGrokker):
     component_class = grok.Traverser
 
@@ -227,7 +235,8 @@
         component.provideAdapter(factory,
                                  adapts=(factory_context, IBrowserRequest),
                                  provides=IBrowserPublisher)
-    
+
+
 class ModulePageTemplateGrokker(grok.InstanceGrokker):
     # this needs to happen before any other grokkers execute that actually
     # use the templates
@@ -239,25 +248,28 @@
         templates.register(name, instance)
         instance._annotateGrokInfo(name, module_info.dotted_name)
 
+
 class FilesystemPageTemplateGrokker(grok.ModuleGrokker):
     # do this early on, but after ModulePageTemplateGrokker, as
     # findFilesystem depends on module-level templates to be
     # already grokked for error reporting
     priority = 999
-    
+
     def register(self, context, module_info, templates):
         templates.findFilesystem(module_info)
 
+
 class SubscriberGrokker(grok.ModuleGrokker):
 
     def register(self, context, module_info, templates):
         subscribers = module_info.getAnnotation('grok.subscribers', [])
-    
+
         for factory, subscribed in subscribers:
             component.provideHandler(factory, adapts=subscribed)
             for iface in subscribed:
                 zope.component.interface.provideInterface('', iface)
 
+
 class StaticResourcesGrokker(grok.ModuleGrokker):
 
     def register(self, context, module_info, templates):
@@ -265,7 +277,7 @@
         # happens to be a package
         if not module_info.isPackage():
             return
-        
+
         resource_path = module_info.getResourcePath('static')
         if os.path.isdir(resource_path):
             static_module = module_info.getSubModuleInfo('static')
@@ -280,18 +292,19 @@
                         "A package can not contain both a 'static' "
                         "resource directory and a module named "
                         "'static.py'", module_info.getModule())
-        
+
         resource_factory = components.DirectoryResourceFactory(
             resource_path, module_info.dotted_name)
         component.provideAdapter(
             resource_factory, (IDefaultBrowserLayer,),
             interface.Interface, name=module_info.dotted_name)
 
+
 class GlobalUtilityDirectiveGrokker(grok.ModuleGrokker):
 
     def register(self, context, module_info, templates):
         infos = module_info.getAnnotation('grok.global_utility', [])
-    
+
         for info in infos:
             if info.provides is None:
                 util.check_implements_one(info.factory)
@@ -299,6 +312,7 @@
                                      provides=info.provides,
                                      name=info.name)
 
+
 class SiteGrokker(grok.ClassGrokker):
     component_class = grok.Site
     priority = 500
@@ -336,7 +350,7 @@
 
                 util.check_implements_one_from_list(provides, info.factory)
                 info.provides = provides[0]
-    
+
         # raise an error in case of any duplicate registrations
         # on the class level (subclassing overrides, see below)
         used = set()
@@ -371,6 +385,7 @@
         component.provideHandler(localUtilityRegistrationSubscriber,
                                  adapts=(factory, grok.IObjectAddedEvent))
 
+
 def localUtilityRegistrationSubscriber(site, event):
     """A subscriber that fires to set up local utilities.
     """
@@ -406,7 +421,8 @@
     # we are done. If this subscriber gets fired again, we therefore
     # do not register utilities anymore
     site.__grok_utilities_installed__ = True
-        
+
+
 class DefinePermissionGrokker(grok.ModuleGrokker):
 
     priority = 1500
@@ -417,6 +433,7 @@
             # TODO permission title and description
             component.provideUtility(Permission(permission), name=permission)
 
+
 class AnnotationGrokker(grok.ClassGrokker):
     component_class = grok.Annotation
  
@@ -452,3 +469,16 @@
             return contained_result
 
         component.provideAdapter(getAnnotation)
+
+
+class ApplicationGrokker(grok.ClassGrokker):
+    component_class = grok.Application
+    priority = 500
+    continue_scanning = True
+
+    def register(self, context, name, factory, module_info, templates):
+        # XXX fail loudly if the same application name is used twice.
+        zope.component.provideUtility(factory,
+                                      provides=grok.interfaces.IApplication,
+                                      name='%s.%s' % (module_info.dotted_name,
+                                                      name))

Added: grok/trunk/src/grok/tests/application/__init__.py
===================================================================
--- grok/trunk/src/grok/tests/application/__init__.py	2007-02-06 23:19:06 UTC (rev 72408)
+++ grok/trunk/src/grok/tests/application/__init__.py	2007-02-07 06:20:13 UTC (rev 72409)
@@ -0,0 +1 @@
+# this is a package


Property changes on: grok/trunk/src/grok/tests/application/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id Rev Date
Name: svn:eol-style
   + native

Added: grok/trunk/src/grok/tests/application/application.py
===================================================================
--- grok/trunk/src/grok/tests/application/application.py	2007-02-06 23:19:06 UTC (rev 72408)
+++ grok/trunk/src/grok/tests/application/application.py	2007-02-07 06:20:13 UTC (rev 72409)
@@ -0,0 +1,35 @@
+"""
+
+After grokking a module that defines an application, the application factory is
+available as a utility::
+
+    >>> grok.grok(__name__)
+    >>> import zope.component
+    >>> import grok.interfaces
+    >>> calendar_app = zope.component.getUtility(grok.interfaces.IApplication,
+    ...                                          name='grok.tests.application.application.Calendar')
+    >>> calendar_app
+    <class 'grok.tests.application.application.Calendar'>
+
+Applications are both containers and sites::
+
+    >>> issubclass(calendar_app, grok.Container)
+    True
+    >>> issubclass(calendar_app, grok.Site)
+    True
+
+Applications can be instanciated without any arguments::
+
+    >>> calendar = calendar_app()
+    >>> calendar
+    <grok.tests.application.application.Calendar object at 0x...>
+
+"""
+
+import grok
+
+
+class Calendar(grok.Application):
+    """A calendar application that knows about ancient
+    calendar systems from the stone age.
+    """


Property changes on: grok/trunk/src/grok/tests/application/application.py
___________________________________________________________________
Name: svn:keywords
   + Id Rev Date
Name: svn:eol-style
   + native

Modified: grok/trunk/src/grok/tests/test_grok.py
===================================================================
--- grok/trunk/src/grok/tests/test_grok.py	2007-02-06 23:19:06 UTC (rev 72408)
+++ grok/trunk/src/grok/tests/test_grok.py	2007-02-07 06:20:13 UTC (rev 72409)
@@ -35,7 +35,7 @@
     for name in ['adapter', 'error', 'view', 'scan', 'event', 'security',
                  'zcml', 'static', 'utility', 'xmlrpc', 'container',
                  'traversal', 'form', 'site', 'grokker', 'directive', 'util',
-                 'baseclass', 'annotation']:
+                 'baseclass', 'annotation', 'application']:
         suite.addTest(suiteFromPackage(name))
     return suite
 



More information about the Checkins mailing list