[Repoze-checkins] r1341 - in repoze.bfg/trunk/repoze/bfg: . tests tests/fixtures

Paul Everitt paul at agendaless.com
Wed Jul 16 12:55:43 EDT 2008


Author: Paul Everitt <paul at agendaless.com>
Date: Wed Jul 16 12:55:42 2008
New Revision: 1341

Log:


Added:
   repoze.bfg/trunk/repoze/bfg/tests/fixtures/minimal.xsl
   repoze.bfg/trunk/repoze/bfg/tests/test_xslt.py
Modified:
   repoze.bfg/trunk/repoze/bfg/template.py

Modified: repoze.bfg/trunk/repoze/bfg/template.py
==============================================================================
--- repoze.bfg/trunk/repoze/bfg/template.py	(original)
+++ repoze.bfg/trunk/repoze/bfg/template.py	Wed Jul 16 12:55:42 2008
@@ -26,6 +26,38 @@
         response = Response(result)
         return response
 
+class XSLTemplateFactory(object):
+    classProvides(ITemplateFactory)
+    implements(IView)
+
+    def __init__(self, path):
+        self.path = path
+
+    def __call__(self, *arg, **kw):
+        node = kw.get("node")
+        processor = get_processor(self.path)
+        result = str(processor(node))
+        response = Response(result)
+        return response
+
+# Manage XSLT processors on a per-thread basis
+import threading
+from lxml import etree
+xslt_pool = threading.local()
+def get_processor(xslt_fn):
+    try:
+        return xslt_pool.processors[xslt_fn]
+    except AttributeError:
+        xslt_pool.processors = {}
+    except KeyError:
+        pass
+
+    # Make a processor and add it to the pool
+    source = etree.ElementTree(file=xslt_fn)
+    proc = etree.XSLT(source)
+    xslt_pool.processors[xslt_fn] = proc
+    return proc
+
 def package_path(package):
     return os.path.abspath(os.path.dirname(package.__file__))
 
@@ -56,3 +88,23 @@
         registerTemplate(template, path)
 
     return template(**kw)
+
+def render_transform(path, **kw):
+    # Render using XSLT
+
+    if not os.path.isabs(path):
+        package_globals = sys._getframe(1).f_globals
+        package_name = package_globals['__name__']
+        package = sys.modules[package_name]
+        prefix = package_path(package)
+        path = os.path.join(prefix, path)
+
+    template = queryUtility(IView, path)
+    node = kw.get("node")
+    if template is None:
+        if not os.path.exists(path):
+            raise ValueError('Missing template file: %s' % path)
+        template = XSLTemplateFactory(path)
+        registerTemplate(template, path)
+
+    return template(**kw)

Added: repoze.bfg/trunk/repoze/bfg/tests/fixtures/minimal.xsl
==============================================================================
--- (empty file)
+++ repoze.bfg/trunk/repoze/bfg/tests/fixtures/minimal.xsl	Wed Jul 16 12:55:42 2008
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+     <xsl:template match="/">
+          <div/>
+     </xsl:template>
+</xsl:stylesheet>

Added: repoze.bfg/trunk/repoze/bfg/tests/test_xslt.py
==============================================================================
--- (empty file)
+++ repoze.bfg/trunk/repoze/bfg/tests/test_xslt.py	Wed Jul 16 12:55:42 2008
@@ -0,0 +1,123 @@
+import unittest
+
+from zope.component.testing import PlacelessSetup
+
+class Base(PlacelessSetup):
+    def setUp(self):
+        PlacelessSetup.setUp(self)
+
+    def tearDown(self):
+        PlacelessSetup.tearDown(self)
+
+    def _zcmlConfigure(self):
+        import repoze.bfg
+        import zope.configuration.xmlconfig
+        zope.configuration.xmlconfig.file('configure.zcml', package=repoze.bfg)
+
+    def _getTemplatePath(self, name):
+        import os
+        here = os.path.abspath(os.path.dirname(__file__))
+        return os.path.join(here, 'fixtures', name)
+        
+class XSLTemplateFactoryTests(unittest.TestCase, Base):
+    def setUp(self):
+        Base.setUp(self)
+
+    def tearDown(self):
+        Base.tearDown(self)
+
+    def _getTargetClass(self):
+        from repoze.bfg.template import XSLTemplateFactory
+        return XSLTemplateFactory
+
+    def _makeOne(self, *arg, **kw):
+        klass = self._getTargetClass()
+        return klass(*arg, **kw)
+
+    def test_instance_conforms_to_IView(self):
+        from zope.interface.verify import verifyObject
+        from repoze.bfg.interfaces import IView
+        path = self._getTemplatePath('minimal.xsl')
+        verifyObject(IView, self._makeOne(path))
+
+    def test_class_conforms_to_IView(self):
+        from zope.interface.verify import verifyClass
+        from repoze.bfg.interfaces import IView
+        verifyClass(IView, self._getTargetClass())
+
+    def test_class_conforms_to_ITemplateFactory(self):
+        from zope.interface.verify import verifyObject
+        from repoze.bfg.interfaces import ITemplateFactory
+        verifyObject(ITemplateFactory, self._getTargetClass())
+
+    def test_call(self):
+        self._zcmlConfigure()
+        minimal = self._getTemplatePath('minimal.xsl')
+        instance = self._makeOne(minimal)
+        from lxml import etree
+        info = etree.Element("info")
+        result = instance(node=info)
+        from webob import Response
+        self.failUnless(isinstance(result, Response))
+        resultstr = """<?xml version="1.0"?>\n<div/>\n"""
+        self.assertEqual(result.app_iter, [resultstr])
+        self.assertEqual(result.status, '200 OK')
+        self.assertEqual(len(result.headerlist), 2)
+
+class RenderTemplateTests(unittest.TestCase, Base):
+    def setUp(self):
+        Base.setUp(self)
+
+    def tearDown(self):
+        Base.tearDown(self)
+
+    def _getFUT(self):
+        from repoze.bfg.template import render_transform
+        return render_transform
+
+    def test_nonabs_unregistered(self):
+        self._zcmlConfigure()
+        from zope.component import queryUtility
+        from repoze.bfg.interfaces import IView
+        minimal = self._getTemplatePath('minimal.xsl')
+        self.assertEqual(queryUtility(IView, minimal), None)
+        render = self._getFUT()
+        from lxml import etree
+        info = etree.Element("info")
+        result = render(minimal, node=info)
+        from webob import Response
+        self.failUnless(isinstance(result, Response))
+        resultstr = """<?xml version="1.0"?>\n<div/>\n"""
+        self.assertEqual(result.app_iter, [resultstr])
+        self.assertEqual(result.status, '200 OK')
+        self.assertEqual(len(result.headerlist), 2)
+        from repoze.bfg.template import XSLTemplateFactory
+        self.failUnless(isinstance(queryUtility(IView, minimal),
+                                   XSLTemplateFactory))
+
+    def test_nonabs_registered(self):
+        self._zcmlConfigure()
+        from zope.component import getGlobalSiteManager
+        from zope.component import queryUtility
+        from repoze.bfg.template import XSLTemplateFactory
+        from repoze.bfg.interfaces import IView
+        minimal = self._getTemplatePath('minimal.xsl')
+        utility = XSLTemplateFactory(minimal)
+        gsm = getGlobalSiteManager()
+        gsm.registerUtility(utility, IView, name=minimal)
+        render = self._getFUT()
+        from lxml import etree
+        info = etree.Element("info")
+        result = render(minimal, node=info)
+        from webob import Response
+        self.failUnless(isinstance(result, Response))
+        resultstr = """<?xml version="1.0"?>\n<div/>\n"""
+        self.assertEqual(result.app_iter, [resultstr])
+        self.assertEqual(result.status, '200 OK')
+        self.assertEqual(len(result.headerlist), 2)
+        self.assertEqual(queryUtility(IView, minimal), utility)
+        
+class DummyView:
+    context = 'context'
+    request = 'request'
+        


More information about the Repoze-checkins mailing list