[KSS-checkins] r49297 - in kukit/kss.demo/branch/kss-zope-transition/kss/demo: . browser selenium_utils tests

reebalazs at codespeak.net reebalazs at codespeak.net
Sun Dec 2 21:04:48 CET 2007


Author: reebalazs
Date: Sun Dec  2 21:04:47 2007
New Revision: 49297

Added:
   kukit/kss.demo/branch/kss-zope-transition/kss/demo/selenium_utils/builder.py
Removed:
   kukit/kss.demo/branch/kss-zope-transition/kss/demo/events.py
   kukit/kss.demo/branch/kss-zope-transition/kss/demo/kss.demo-meta.zcml
   kukit/kss.demo/branch/kss-zope-transition/kss/demo/meta.zcml
   kukit/kss.demo/branch/kss-zope-transition/kss/demo/registry.py
Modified:
   kukit/kss.demo/branch/kss-zope-transition/kss/demo/browser/registry.py
   kukit/kss.demo/branch/kss-zope-transition/kss/demo/configure.zcml
   kukit/kss.demo/branch/kss-zope-transition/kss/demo/interfaces.py
   kukit/kss.demo/branch/kss-zope-transition/kss/demo/tests/test_demoview.py
Log:
Register demos from plugins

Modified: kukit/kss.demo/branch/kss-zope-transition/kss/demo/browser/registry.py
==============================================================================
--- kukit/kss.demo/branch/kss-zope-transition/kss/demo/browser/registry.py	(original)
+++ kukit/kss.demo/branch/kss-zope-transition/kss/demo/browser/registry.py	Sun Dec  2 21:04:47 2007
@@ -1,9 +1,10 @@
 
-from kss.demo.interfaces import IKSSDemoRegistry
+from kss.zope.interfaces import IKSSPluginRegistry
 from zope.publisher.interfaces.browser import IBrowserPublisher
 from zope.publisher.interfaces import NotFound
 from zope.component import getUtility
 from zope.interface import implements
+from kss.demo.selenium_utils.builder import getSeleniumTestsFromSuite, cookSeleniumTests
 try:
     from Products.Five import BrowserView
     BrowserView         # make pyflakes happy
@@ -14,8 +15,8 @@
 
     def getSortedDemos(self):
         """Get demos"""
-        registry = getUtility(IKSSDemoRegistry)
-        return registry.getSortedDemos()
+        registry = getUtility(IKSSPluginRegistry)
+        return registry.zope_demos()
 
     def getDemoGroups(self):
         """Get demos groupped by plugin_namespace, category"""
@@ -89,6 +90,13 @@
         into the file seltest_all.pty in the directory
         of kss.demo.selenium_utils .
         """
-        registry = getUtility(IKSSDemoRegistry)
-        registry.cookSeleniumTests()
-        return "Selenium tests cooked OK. (%i)" % (len(registry.selenium_tests), )
+        registry = getUtility(IKSSPluginRegistry)
+        suites = registry.zope_selenium_testsuites()
+        # Extract filenames from all suites
+        filenames = []
+        for owner_instance, suite in suites:
+            filenames.extend(getSeleniumTestsFromSuite(owner_instance, suite))
+        # Cook them. This will create seltest_all.py. 
+        cookSeleniumTests(filenames)
+        # We are done.
+        return "Selenium tests cooked OK. (%i) suites, (%i) files" % (len(suites), len(filenames))

Modified: kukit/kss.demo/branch/kss-zope-transition/kss/demo/configure.zcml
==============================================================================
--- kukit/kss.demo/branch/kss-zope-transition/kss/demo/configure.zcml	(original)
+++ kukit/kss.demo/branch/kss-zope-transition/kss/demo/configure.zcml	Sun Dec  2 21:04:47 2007
@@ -50,16 +50,4 @@
   <!-- Finally, include the browser packages -->
   <include package=".browser" />
 
-  <!-- Bind my own listener to dispatch events to
-       demo components.
-  -->
-  <subscriber handler=".events.dispatchRegistration"/>
-
-  <!-- Register my registry as a global utility -->
-  <utility
-    factory=".registry.KSSDemoRegistry"
-    provides="kss.demo.interfaces.IKSSDemoRegistry"
-    permission="zope.Public"
-    />
-
 </configure>

Deleted: /kukit/kss.demo/branch/kss-zope-transition/kss/demo/events.py
==============================================================================
--- /kukit/kss.demo/branch/kss-zope-transition/kss/demo/events.py	Sun Dec  2 21:04:47 2007
+++ (empty file)
@@ -1,43 +0,0 @@
-
-import zope.component
-from zope.component.interfaces import (
-    IUtilityRegistration,
-    IRegistrationEvent,
-    )
-from interfaces import (
-    IKSSDemoResource,
-    IKSSSeleniumTestResource,
-    IKSSDemoRegistrationEvent,
-    IKSSDemoRegistryEvent,
-    IKSSDemoRegistry
-    )
-from zope.interface import implements
-
-class KSSDemoRegistrationEvent(object):
-    """Redispatch of registration for demo resource utilities"""
-    implements(IKSSDemoRegistrationEvent)
-
-class KSSDemoRegistryEvent(object):
-    """Redispatch of registration for demo registry utilities"""
-    implements(IKSSDemoRegistryEvent)
-
- at zope.component.adapter(IUtilityRegistration, IRegistrationEvent)
-def dispatchRegistration(registration, event):
-    """When a demo utility is registered, add it to the registry.
-    When a demo utility is registered,  
-    event handler registered for the particular component registered,
-    the registration and the event.
-    """
-    component = registration.component
-    # Only dispatch registration of the interesting utilities.
-    if IKSSDemoResource.providedBy(component) or \
-            IKSSSeleniumTestResource.providedBy(component):
-        new_event = KSSDemoRegistrationEvent()
-        handlers = zope.component.subscribers((component, registration, event, new_event), None)
-        for handler in handlers:
-            pass # getting them does the work
-    if IKSSDemoRegistry.providedBy(component):
-        new_event = KSSDemoRegistryEvent()
-        handlers = zope.component.subscribers((component, registration, event, new_event), None)
-        for handler in handlers:
-            pass # getting them does the work

Modified: kukit/kss.demo/branch/kss-zope-transition/kss/demo/interfaces.py
==============================================================================
--- kukit/kss.demo/branch/kss-zope-transition/kss/demo/interfaces.py	(original)
+++ kukit/kss.demo/branch/kss-zope-transition/kss/demo/interfaces.py	Sun Dec  2 21:04:47 2007
@@ -50,101 +50,3 @@
         description=u'Relative directory path, contains *.html selenium tests',
         required=False,
         )
-
-# --
-# Resource definition interfaces
-# --
-
-class IKSSDemoResource(Interface):
-    """An utility that a demo needs to register"""
-
-    # list of IKSSDemo
-    demos = List(
-        title=u"demos",
-        description=u'The ordered list of demos contained in this plugin',
-        required=True,
-        )
-
-class IKSSSeleniumTestResource(Interface):
-    """An utility that a demo needs to register"""
-
-    # list of IKSSSeleniumTestDir
-    selenium_tests = List(
-        title=u"selenium tests",
-        description=u'The list of selenium test directories contained in this plugin',
-        required=True,
-        )
-
-# --
-# The registry itself
-# --
-
-class IKSSDemoRegistry(Interface):
-    """Faciliates registration of demos.
-
-    Implementations must look after the IKSSDemoResource
-    adapters, and use their content to set up themselves.
-    """
-
-    def registerDemo(demo):
-        """Register a demo
-
-        It has the attributes specified in IKSSDemo:
-
-        plugin_namespace - string with the name of the plugin.
-                           Or: "" when it is the core part.
-
-        category         - text that will appear as the title of the
-                           category. "" if out of category.
-
-        demo_page        - (relative) url of the demo page. This should
-                           traverse on ISimpleContent.
-
-        title            - Title of the demo. This also identifies it
-                           for removal.
-        """
- 
-    def unregisterDemo(demo):
-        """Unregister the given demo."""
-
-    def getSortedDemos():
-        """Get the (sorted) list of demos"""
-
-class IKSSSeleniumTestRegistry(Interface):
-    """Faciliates registration of demos.
-
-    Implementations must look after the IKSSSeleniumTestResource
-    adapters, and use their content to set up themselves.
-    """
-
-    def registerSeleniumTestFile(test_filename):
-        """Register a selenium test directory
-
-        It test_dir has the "filename" attributes specified in IKSSSeleniumTest.
-        """
-    
-    def unregisterSeleniumTestFile(test_filename):
-        """Unregister the given test directory."""
-
-    def cookSeleniumTests():
-        """Cook selenium tests
-
-        The *.html tests from each plugin are produced
-        into the file seltest_all.pty in the directory
-        of kss.demo.selenium_utils .
-        """
-
-# --
-# Event that gets redispatched, for allowing
-# the listeners to filter on component
-# --
-
-class IKSSDemoRegistrationEvent(Interface):
-    """Redispatched event for registration of
-    IKSSDemoRegistration utilities (resources).
-    """
-
-class IKSSDemoRegistryEvent(Interface):
-    """Redispatched event for registration of
-    IKSSDemoRegistry utilities.
-    """

Deleted: /kukit/kss.demo/branch/kss-zope-transition/kss/demo/kss.demo-meta.zcml
==============================================================================
--- /kukit/kss.demo/branch/kss-zope-transition/kss/demo/kss.demo-meta.zcml	Sun Dec  2 21:04:47 2007
+++ (empty file)
@@ -1,3 +0,0 @@
-
-<include package="kss.demo" file="meta.zcml" />
-

Deleted: /kukit/kss.demo/branch/kss-zope-transition/kss/demo/meta.zcml
==============================================================================
--- /kukit/kss.demo/branch/kss-zope-transition/kss/demo/meta.zcml	Sun Dec  2 21:04:47 2007
+++ (empty file)
@@ -1,6 +0,0 @@
-<configure
-     xmlns="http://namespaces.zope.org/meta">
-
-   <include package=".configfeature" file="meta.zcml"/>
-
-</configure>

Deleted: /kukit/kss.demo/branch/kss-zope-transition/kss/demo/registry.py
==============================================================================
--- /kukit/kss.demo/branch/kss-zope-transition/kss/demo/registry.py	Sun Dec  2 21:04:47 2007
+++ (empty file)
@@ -1,254 +0,0 @@
-from zope.interface import implements
-from zope.component import (
-    adapter, 
-    getSiteManager,
-    )
-from interfaces import (
-    IKSSDemoRegistry,
-    IKSSSeleniumTestRegistry,
-    IKSSDemoResource,
-    IKSSSeleniumTestResource,
-    IKSSDemoRegistrationEvent,
-    IKSSDemoRegistryEvent,
-    )
-from zope.component.interfaces import (
-    IUtilityRegistration,
-    IRegistered,
-    IUnregistered,
-    )
-import sys, os, re, textwrap
-from elementtree import HTMLTreeBuilder
-from string import Template
-import kss.demo.selenium_utils
-# shut the mouth of pyflakes
-kss.demo.selenium_utils
-
-# --
-# Registry implementation for use with Zope
-# --
-
-def getRootDirOfModule(module_name):
-    return os.path.dirname(sys.modules[module_name].__file__)
-
-def getRootDirOfClass(cls):
-    return getRootDirOfModule(cls.__module__)
-
-def getRootDirOfInstance(obj):
-    return getRootDirOfClass(obj.__class__)
-
-# Create a mesh of provided interfaces
-# This is needed, because an utility must have a single interface.
-class IRegistry(IKSSDemoRegistry, IKSSSeleniumTestRegistry):
-    pass
-
-class KSSDemoRegistry(object):
-    """KSS demo registry.
-    """
-    implements(IRegistry)
-
-    def __init__(self):
-        # We will set up my handlers to get notified of new plugins
-        # (works via redispatching by events.py)
-        site = getSiteManager()
-        # registry for demos
-        self.demos_dict = {}
-        self.demos = []
-        self.demos_are_sorted = False
-        site.registerHandler(self.registerDemosFromPlugin)
-        site.registerHandler(self.unregisterDemosFromPlugin)
-        site.registerHandler(self.registerEarlierDemos)
-        # registry for selenium tests
-        self.selenium_tests = []
-        site.registerHandler(self.registerSeleniumTestsFromPlugin)
-        site.registerHandler(self.unregisterSeleniumTestsFromPlugin)
-        # ... the rest of setup will be done from registerEarlierDemos
-
-    @adapter(IKSSDemoRegistry, IUtilityRegistration, IRegistered, IKSSDemoRegistryEvent)
-    def registerEarlierDemos(self, registry, registration=None, event=None, new_event=None):
-        """Make sure that the resources registered earlier, are added
-         (so this is a listener to the registration of myself
-         which is needed because CA is not ready at time of the __init__)
-        """
-        if registry != self:
-            # The utility only register on itself.
-            return
-        site = getSiteManager()
-        for name, plugin in site.getUtilitiesFor(IKSSDemoResource):
-            for demo in plugin.demos:
-                self.registerDemo(demo)
-
-    @adapter(IKSSDemoResource, IUtilityRegistration, IRegistered, IKSSDemoRegistrationEvent)
-    def registerDemosFromPlugin(self, plugin, registration=None, event=None, new_event=None):
-        """Add a demo collection to the registry.
-        """
-        for demo in plugin.demos:
-            self.registerDemo(demo)
-
-    @adapter(IKSSDemoResource, IUtilityRegistration, IUnregistered, IKSSDemoRegistrationEvent)
-    def unregisterDemosFromPlugin(self, plugin, registration=None, event=None, new_event=None):
-        """Remove a demo collection from the registry.
-        """
-        for demo in plugin.demos:
-            self.unregisterDemo(demo)
-
-    def registerDemo(self, demo):
-        """Register a demo
-
-        It has the attributes specified in IKSSDemo:
-
-        plugin_namespace - string with the name of the plugin.
-                           Or: "" when it is the core part.
-
-        category         - text that will appear as the title of the
-                           category. "" if out of category.
-
-        demo_page        - (relative) url of the demo page. This should
-                           traverse on ISimpleContent.
-
-        title            - Title of the demo. This also identifies it
-                           for removal.
-        """
-        key = demo.plugin_namespace, demo.category, demo.page_url
-        if key in self.demos:
-            raise Exception, 'The demo for %s has already been registered. Cannot add.' % (key, )
-        self.demos_dict[key] = demo
-        self.demos.append(demo)
-        self.demos_are_sorted = False
-
-    def unregisterDemo(self, demo):
-        """Unregister the given demo."""
-        key = demo.plugin_namespace, demo.category, demo.demo_page
-        try:
-            value = self.demos_dict[key]
-        except KeyError:
-            raise Exception, 'The demo for %s is yet unregistered. Cannot remove.' % (key, )
-        del self.demos_dict[key]
-        self.demos.remove(value)
-
-    def getSortedDemos(self):
-        """Get the (sorted) list of demos"""
-        if not self.demos_are_sorted:
-            self.demos.sort(key=lambda demo: (
-                demo.plugin_namespace,
-                demo.category,
-                ))
-            self.demos_are_sorted = True
-        return list(self.demos)
-
-    # --
-    # Selenium tests
-    # --
-
-    @staticmethod
-    def _getSeleniumTestsFromPlugin(plugin):
-        test_filenames = []
-        root_dir = getRootDirOfInstance(plugin)
-        for selenium_test_directory in plugin.selenium_tests:
-            tests_root_dir = os.path.join(root_dir, selenium_test_directory.test_directory)
-            for test_filename in os.listdir(tests_root_dir):
-                if test_filename.lower().endswith('.html') or \
-                        test_filename.endswith('.htm'):
-                    test_filenames.append(os.path.join(tests_root_dir, test_filename))
-        return test_filenames
-
-    @adapter(IKSSSeleniumTestResource, IUtilityRegistration, IRegistered, IKSSDemoRegistrationEvent)
-    def registerSeleniumTestsFromPlugin(self, plugin, registration=None, event=None, new_event=None):
-        """Add a demo collection to the registry.
-        """
-        for test_filename in self._getSeleniumTestsFromPlugin(plugin):
-            self.registerSeleniumTestFile(test_filename)
-
-    @adapter(IKSSSeleniumTestResource, IUtilityRegistration, IUnregistered, IKSSDemoRegistrationEvent)
-    def unregisterSeleniumTestsFromPlugin(self, plugin, registration=None, event=None, new_event=None):
-        """Remove a demo collection from the registry.
-        """
-        for test_filename in self._getSeleniumTestsFromPlugin(plugin):
-            self.registerSeleniumTestFile(test_filename)
-
-    def registerSeleniumTestFile(self, test_filename):
-        """Register a selenium test by absolute filename
-        """
-        if test_filename in self.selenium_tests:
-            raise Exception, 'The selenium test for %s has already been registered. Cannot add.' % (test_filename, )
-        self.selenium_tests.append(test_filename)
-
-    def unregisterSeleniumTestFile(self, test_filename):
-        """Unregister the given selenium test."""
-        try:
-            del self.selenium_tests[test_filename]
-        except KeyError:
-            raise Exception, 'The selenium test for %s is yet unregistered. Cannot remove.' % (test_filename, )
-
-    template = Template(textwrap.dedent('''\
-            from seleniumtestcase import SeleniumTestCase
-            import unittest, time
-
-            class seltest_$testname(SeleniumTestCase):
-
-            $tests
-
-            def test_suite():
-                return unittest.makeSuite(seltest_$testname)
-
-            if __name__ == "__main__":
-                unittest.main()
-            '''))
-
-    variable_regexp = re.compile('\$\{(?P<varname>\w*)\}')
-    @classmethod
-    def formatcommand(cls, command, *args):
-        if not command:
-            return '' # Change this to raise an exception?
-
-        arguments = []
-        for arg in args:
-            if not arg:
-                continue
-            matched = cls.variable_regexp.match(arg)
-            if matched is None:
-                arguments.append('"%s"'%arg)
-            else:
-                arguments.append("self.getVar('%s')"%matched.group('varname'))
-        return 'self.%s(%s)' % (command, ', '.join(arguments))
-
-    def cookSeleniumTests(self):
-        """Cook selenium tests
-
-        The *.html tests from each plugin are produced
-        into the file seltest_all.pty in the directory
-        of kss.demo.selenium_utils .
-        """
-        # Try to open the file for writing.
-        output_dir =  getRootDirOfModule('kss.demo.selenium_utils')
-        output_filename = os.path.join(output_dir, 'seltest_all.py')
-        try:
-            f = open(output_filename, 'wb')
-        except IOError, exc:
-            raise IOError, ('Cannot open file "%s" for writing. '
-                            'Make sure zope process has write access in directory. '
-                            '["%s"]') \
-                            % (output_filename, exc)
-
-        htmlparser = HTMLTreeBuilder.TreeBuilder()
-        tests = []
-        for filename in self.selenium_tests:
-            tree = HTMLTreeBuilder.parse(filename)
-            root = tree.getroot()
-
-            try:
-                testname = root.find('.//title').text
-            except AttributeError:
-                continue
-            commands = []
-            for row in root.findall('.//tbody/tr'):
-                commands.append(self.formatcommand(*[td.text for td in row.findall('td')]))
-
-            testfilename = 'seltest_%s.py' % testname
-            testbody='    def test_%s(self):\n'%testname+' '*8+'\n        '.join(commands)+'\n'
-            tests.append(testbody)
-
-        f.write(self.template.substitute(dict(
-            testname=testname,
-            tests='\n'.join(tests),
-            )))
-        f.close()

Added: kukit/kss.demo/branch/kss-zope-transition/kss/demo/selenium_utils/builder.py
==============================================================================
--- (empty file)
+++ kukit/kss.demo/branch/kss-zope-transition/kss/demo/selenium_utils/builder.py	Sun Dec  2 21:04:47 2007
@@ -0,0 +1,110 @@
+
+import sys, os, re, textwrap
+from elementtree import HTMLTreeBuilder
+from string import Template
+
+# --
+# This is used to build the seltest_all.py file into the same directory.
+# --
+
+# root directory finding code
+def getRootDirOfModule(module_name):
+    return os.path.dirname(sys.modules[module_name].__file__)
+
+def getRootDirOfClass(cls):
+    return getRootDirOfModule(cls.__module__)
+
+def getRootDirOfInstance(obj):
+    return getRootDirOfClass(obj.__class__)
+
+def getSeleniumTestsFromSuite(owner_instance, suite):
+    """Get absolute filenames of all tests from the suite.
+    Suite contains the directory that we need to find.
+    owner_instance is used for the directory finding,
+    the suite's directory is traversed relative from that.
+    """
+    test_filenames = []
+    # The owner instance is only used to traverse the sute directory
+    # relative from it.
+    root_dir = getRootDirOfInstance(owner_instance)
+    tests_root_dir = os.path.join(root_dir, suite.test_directory)
+    for test_filename in os.listdir(tests_root_dir):
+        if test_filename.lower().endswith('.html') or \
+                test_filename.endswith('.htm'):
+            test_filenames.append(os.path.join(tests_root_dir, test_filename))
+    return test_filenames
+
+template = Template(textwrap.dedent('''\
+        from seleniumtestcase import SeleniumTestCase
+        import unittest, time
+
+        class seltest_$testname(SeleniumTestCase):
+
+        $tests
+
+        def test_suite():
+            return unittest.makeSuite(seltest_$testname)
+
+        if __name__ == "__main__":
+            unittest.main()
+        '''))
+
+variable_regexp = re.compile('\$\{(?P<varname>\w*)\}')
+
+def formatcommand(command, *args):
+    if not command:
+        return '' # Change this to raise an exception?
+
+    arguments = []
+    for arg in args:
+        if not arg:
+            continue
+        matched = variable_regexp.match(arg)
+        if matched is None:
+            arguments.append('"%s"'%arg)
+        else:
+            arguments.append("self.getVar('%s')"%matched.group('varname'))
+    return 'self.%s(%s)' % (command, ', '.join(arguments))
+
+
+
+def cookSeleniumTests(filenames):
+    """Cook selenium tests
+    """
+    # Try to open the file for writing.
+    output_dir =  getRootDirOfModule('kss.demo.selenium_utils')
+    output_filename = os.path.join(output_dir, 'seltest_all.py')
+    try:
+        f = open(output_filename, 'wb')
+    except IOError, exc:
+        raise IOError, ('Cannot open file "%s" for writing. '
+                        'Make sure zope process has write access in directory. '
+                        '["%s"]') \
+                        % (output_filename, exc)
+
+    htmlparser = HTMLTreeBuilder.TreeBuilder()
+    tests = []
+
+    # Now, we find all filenames that are inthe suite passed to us.
+
+    for filename in filenames:
+        tree = HTMLTreeBuilder.parse(filename)
+        root = tree.getroot()
+
+        try:
+            testname = root.find('.//title').text
+        except AttributeError:
+            continue
+        commands = []
+        for row in root.findall('.//tbody/tr'):
+            commands.append(formatcommand(*[td.text for td in row.findall('td')]))
+
+        testfilename = 'seltest_%s.py' % testname
+        testbody='    def test_%s(self):\n'%testname+' '*8+'\n        '.join(commands)+'\n'
+        tests.append(testbody)
+
+    f.write(template.substitute(dict(
+        testname=testname,
+        tests='\n'.join(tests),
+        )))
+    f.close()

Modified: kukit/kss.demo/branch/kss-zope-transition/kss/demo/tests/test_demoview.py
==============================================================================
--- kukit/kss.demo/branch/kss-zope-transition/kss/demo/tests/test_demoview.py	(original)
+++ kukit/kss.demo/branch/kss-zope-transition/kss/demo/tests/test_demoview.py	Sun Dec  2 21:04:47 2007
@@ -36,7 +36,6 @@
     class layer(KSSViewTestCase.layer):
         @classmethod
         def setUp(cls):
-            load_config('meta.zcml', package=kss.demo)
             load_config('configure.zcml', package=kss.demo)
 
     def afterSetUp(self):


More information about the Kukit-checkins mailing list