Ticket #6237: t.w.template-adapter-support-6237.patch

File t.w.template-adapter-support-6237.patch, 4.4 KB (added by tom.prince, 4 years ago)

Patch to add support for adapters

  • twisted/web/_flatten.py

    === modified file 'twisted/web/_flatten.py'
     
    179179        yield root.addCallback(
    180180            lambda result: (result, _flattenElement(request, result, slotData,
    181181                                             renderFactory, inAttribute)))
    182     elif IRenderable.providedBy(root):
    183         result = root.render(request)
    184         yield _flattenElement(request, result, slotData, root, inAttribute)
    185182    else:
    186         raise UnsupportedType(root)
     183        try:
     184            renderer = IRenderable(root)
     185        except TypeError:
     186            raise UnsupportedType(root)
     187        result = renderer.render(request)
     188        yield _flattenElement(request, result, slotData, renderer, inAttribute)
    187189
    188190
    189191def _flattenTree(request, root):
  • twisted/web/test/test_flatten.py

    === modified file 'twisted/web/test/test_flatten.py'
     
    1 
    21# Copyright (c) Twisted Matrix Laboratories.
    32# See LICENSE for details.
    43
     
    98
    109from twisted.trial.unittest import TestCase
    1110from twisted.internet.defer import succeed, gatherResults
     11from twisted.python import components
     12from twisted.python.test.test_components import RegistryUsingMixin
    1213from twisted.web._stan import Tag
    1314from twisted.web._flatten import flattenString
    1415from twisted.web.error import UnfilledSlot, UnsupportedType, FlattenerError
     
    1718from twisted.web.test._util import FlattenTestCase
    1819
    1920
     21
     22class FakeElement(object):
     23    """
     24    A fake L{IRenderable} that returns a document with a specified
     25    hole, to test both parts of the L{IRenderable} interface.
     26
     27    @type testcase: L{TestCase}
     28    @ivar testcase: the test case to which asserts should be directed
     29    """
     30
     31    implements(IRenderable)
     32
     33    def __init__(self, testcase):
     34        self.testcae = testcase
     35
     36
     37    def render(self, req):
     38        """
     39        Returns a document with holes to be filled by
     40        C{lookupRenderMethod}.
     41
     42        @param req: (ignored)
     43
     44        @return: a document
     45        """
     46        return tags.p(
     47            'hello, ',
     48            tags.transparent(render='test'), ' - ',
     49            tags.transparent(render='test'))
     50
     51
     52    def lookupRenderMethod(self, name):
     53        """
     54        Returns a method to handle the hole C{test}, and asserts that the hole
     55        is in fact C{test}.
     56
     57        @param name: the string C{"test"}
     58        @return: render method for C{test} hole
     59        """
     60        self.testcase.assertEqual(name, 'test')
     61        return lambda ign, node: node('world')
     62
     63
     64
    2065class TestSerialization(FlattenTestCase):
    2166    """
    2267    Tests for flattening various things.
     
    163208        """
    164209        Test that flattening respects all of the IRenderable interface.
    165210        """
    166         class FakeElement(object):
    167             implements(IRenderable)
    168             def render(ign,ored):
    169                 return tags.p(
    170                     'hello, ',
    171                     tags.transparent(render='test'), ' - ',
    172                     tags.transparent(render='test'))
    173             def lookupRenderMethod(ign, name):
    174                 self.assertEqual(name, 'test')
    175                 return lambda ign, node: node('world')
    176 
    177211        return gatherResults([
    178             self.assertFlattensTo(FakeElement(), '<p>hello, world - world</p>'),
     212            self.assertFlattensTo(FakeElement(self), '<p>hello, world - world</p>'),
    179213        ])
    180214
    181215
     
    209243        return self.assertFlatteningRaises(None, UnsupportedType)
    210244
    211245
     246
     247class TestAdapterSerialization(RegistryUsingMixin, FlattenTestCase):
     248    """
     249    Tests for flattening various things that use the global adapter registry.
     250    """
     251
     252    def test_serializeAdaptableRender(self):
     253        """
     254        Tests that flattening an object adaptable to an L{IRenderable} uses
     255        the adapter.
     256        """
     257        class FakeAdaptee(object):
     258            pass
     259
     260        components.registerAdapter(lambda _: FakeElement(self), FakeAdaptee, IRenderable)
     261
     262        return gatherResults([
     263            self.assertFlattensTo(FakeAdaptee(), '<p>hello, world - world</p>'),
     264        ])
     265
     266
     267
     268
    212269# Use the co_filename mechanism (instead of the __file__ mechanism) because
    213270# it is the mechanism traceback formatting uses.  The two do not necessarily
    214271# agree with each other.  This requires a code object compiled in this file.