1
# Copyright (c) 2004 Divmod.
2
# See LICENSE for details.
5
from twisted.internet import defer
7
from nevow import context, inevow
8
from nevow import testutil
9
from nevow.flat import twist
10
from nevow.util import Deferred
12
from nevow import rend, loaders, tags
24
class RenderHelper(testutil.TestCase):
26
req = testutil.FakeRequest()
27
self.r.renderHTTP(context.PageContext(tag=self.r, parent=context.RequestContext(tag=req)))
31
class LaterRenderTest(RenderHelper):
36
docFactory=loaders.stan(
38
'Hello ', tags.invisible[tags.invisible[tags.invisible[tags.invisible[deferit]]]],
44
def test_deferredSupport(self):
46
self.assertEquals(req.v, '<html>Hello ')
47
self.d.callback("world")
48
self.assertEquals(req.v, '<html>Hello world')
50
self.assertEquals(req.v, '<html>Hello world.</html>')
53
def test_deferredSupport2(self):
55
self.assertEquals(req.v, '<html>Hello ')
57
self.assertEquals(req.v, '<html>Hello ')
58
self.d.callback("world")
59
self.assertEquals(req.v, '<html>Hello world.</html>')
61
def test_deferredSupport3(self):
62
self.r.buffered = True
64
self.assertEquals(req.v, '')
65
self.d.callback("world")
66
self.assertEquals(req.v, '')
68
self.assertEquals(req.v, '<html>Hello world.</html>')
70
def test_renderNestedDeferredCallables(self):
72
Test flattening of a renderer which returns a Deferred which fires with
73
a renderer which returns a Deferred.
75
def render_inner(ctx, data):
76
return defer.succeed('')
78
def render_outer(ctx, data):
79
return defer.succeed(render_inner)
81
ctx = context.WovenContext()
82
ctx.remember(None, inevow.IData)
85
d = twist.deferflatten(render_outer, ctx, out.append)
87
self.assertEquals(out, [''])
88
d.addCallback(flattened)
92
def test_renderNestedDeferredErrorHandling(self):
94
Test that flattening a renderer which returns a Deferred which fires
95
with a renderer which raises an exception causes the outermost Deferred
98
class NestedException(Exception):
101
def render_inner(ctx, data):
102
raise NestedException()
104
def render_outer(ctx, data):
105
return defer.succeed(render_inner)
107
ctx = context.WovenContext()
108
ctx.remember(None, inevow.IData)
111
d = twist.deferflatten(render_outer, ctx, out.append)
112
return self.assertFailure(d, NestedException)
115
class LaterDataTest(RenderHelper):
116
def data_later(self, context, data):
119
def data_later2(self, context, data):
125
self.r = rend.Page(docFactory=loaders.stan(
126
tags.html(data=self.data_later)[
127
'Hello ', str, ' and '
129
tags.span(data=self.data_later2, render=str)]))
131
def test_deferredSupport(self):
132
req = self.renderIt()
133
self.assertEquals(req.v, '')
134
self.d.callback("world")
135
self.assertEquals(req.v, '<html>Hello world and goodbye world')
136
self.d2.callback(".")
137
self.assertEquals(req.v, '<html>Hello world and goodbye world.</html>')
140
class SuperLaterDataTest(RenderHelper):
141
def test_reusedDeferredSupport(self):
143
Two occurrences of a particular slot are each replaced with the
144
result of the Deferred which is used to fill that slot.
147
tags.slot('foo'), tags.slot('foo')]
148
doc.fillSlots('foo', defer.succeed(tags.span['Foo!!!']))
149
self.r = rend.Page(docFactory=loaders.stan(doc))
150
req = self.renderIt()
151
self.assertEquals(req.v, '<html><span>Foo!!!</span><span>Foo!!!</span></html>')
154
def test_rendererCalledOnce(self):
156
Make sure that if a Deferred fires with a render function that the
157
render function is called only once.
160
def recorder(ctx, data):
162
return str(len(calls))
163
doc = tags.html[tags.directive('renderer')]
164
class RendererPage(rend.Page):
165
docFactory = loaders.stan(doc)
166
def render_renderer(self, ctx, data):
167
return defer.succeed(recorder)
168
self.r = RendererPage()
169
req = self.renderIt()
170
self.assertEquals(req.v, '<html>1</html>')