# Copyright (c) 2004 Divmod.
# See LICENSE for details.
from __future__ import generators
from nevow import context
from nevow import flat
from nevow import rend
from nevow import testutil
from nevow import loaders
from nevow import util
class req(testutil.FakeRequest):
def __init__(self):
testutil.FakeRequest.__init__(self)
self.d = util.Deferred()
self.accumulator = ''
def write(self, data):
testutil.FakeRequest.write(self, data)
self.accumulator+=data
def finish(self):
testutil.FakeRequest.finish(self)
self.d.callback(self.accumulator)
def deferredRender(res):
defres = req()
d = res.renderHTTP(context.PageContext(tag=res, parent=context.RequestContext(tag=defres)))
def accumulated(result, req):
return req.accumulator
return util.deferredResult(d.addCallback(accumulated, defres), timeout=1)
class TestHTMLRenderer(testutil.TestCase):
'''Test basic rendering behaviour'''
xhtml = '''
TestHello!
'''
def test_stringTemplate(self):
r = rend.Page(docFactory=loaders.htmlstr(self.xhtml))
result = deferredRender(r)
self.assertEquals(result, self.xhtml)
def test_diskTemplate(self):
temp = self.mktemp()
open(temp, 'w').write(self.xhtml)
r = rend.Page(docFactory=loaders.htmlfile(temp))
result = deferredRender(r)
self.assertEquals(result, self.xhtml)
class TestStandardRenderers(testutil.TestCase):
def test_diskTemplate(self):
temp = self.mktemp()
open(temp, 'w').write("""
This is some template data!
This is a header
This node will be replaced entirely (including the span)
""")
class TemplateRenderer(rend.Page):
def data_theTitle(self, context, data):
return "THE TITLE"
def data_theHead(self, context, data):
return "THE HEADER"
def data_someDummyText(self, context, data):
return "SOME DUMMY TEXT"
def render_string(self, context, data):
"""The rule is, whatever a renderer returns *replaces* the node that came in
so if we want this data to *fill* the node the directive was on, we have to
do it explicitly
"""
## This could also be written as:
# return context.tag.clear()[ data ]
## choose your poison
tag = context.tag.clear()
tag.children.append(data)
return tag
def render_replaceNode(self, context, data):
"""Render the current node by replacing whatever was there (including the
node itself) with the current data.
"""
return data
tr = TemplateRenderer(docFactory=loaders.htmlfile(temp))
result = deferredRender(tr)
self.assertEquals(
result,
'THE TITLETHE HEADER
SOME DUMMY TEXT'
)
def test_sequence(self):
"""Test case provided by mg
"""
temp = self.mktemp()
open(temp, 'w').write("""
""")
class TemplateRenderer(rend.Page):
def data_aList(self,context,data):
return ["one","two","three"]
tr = TemplateRenderer(docFactory=loaders.htmlfile(temp))
result = deferredRender(tr)
self.assertEquals(
result, '- one
- two
- three
',
"Whoops. We didn't get what we expected!"
)
def test_sequence2(self):
"""Test case provided by radix
"""
temp = self.mktemp()
open(temp, 'w').write("""
""")
class TemplateRenderer(rend.Page):
def data_aList(self,context,data):
return ["one","two","three"]
tr = TemplateRenderer(docFactory=loaders.htmlfile(temp))
result = deferredRender(tr)
self.assertEquals(
result, '- one
- two
- three
',
"Whoops. We didn't get what we expected!"
)
def test_slots(self):
"""test case provided by mg! thanks
"""
temp = self.mktemp()
open(temp,'w').write("""
""")
class Renderer(rend.Page):
def data_aDict(self,context,data):
return {'1':'one','2':'two','3':'three','4':'four'}
def render_slots(self,context,data):
for name,value in data.items():
context.fillSlots(name, value)
return context.tag
result = deferredRender(Renderer(docFactory=loaders.htmlfile(temp)))
self.assertEquals(
result,
"",
"Whoops. We didn't get what we expected!")
def test_patterns(self):
temp = self.mktemp()
open(temp,'w').write("""
ONE
TWO
THREE
""")
class Mine(rend.Page):
def render_foo(self, context, data):
return context.tag.allPatterns(data)
result = deferredRender(Mine("one", docFactory=loaders.htmlfile(temp)))
self.assertEquals(result, 'ONE')
result = deferredRender(Mine("two", docFactory=loaders.htmlfile(temp)))
self.assertEquals(result, 'TWO')
result = deferredRender(Mine("three", docFactory=loaders.htmlfile(temp)))
self.assertEquals(result, 'THREE')
class TestSubclassAsRenderAndDataFactory(testutil.TestCase):
def test_rendererSubclass(self):
from nevow import tags
class Subclass(rend.Page):
docFactory = loaders.stan(tags.html[
tags.div(data=tags.directive("hello"))[
str
],
tags.span(render=tags.directive("world"))
])
def data_hello(self, context, data):
self.helloCalled = True
return "hello"
def render_world(self, context, data):
return "world"
sr = Subclass()
result = deferredRender(sr)
self.assertSubstring('hello', result)
self.assertSubstring('world', result)
self.assertEquals(result,
"hello
world"
)
class TestXmlFileWithSlots(testutil.TestCase):
def test_slotWithCharacterData(self):
"""Test that xml templates with slots that contain content can be
loaded"""
template = 'stuff
'
doc = loaders.xmlstr(template).load()
class TestAttrReplacement(testutil.TestCase):
def testXML(self):
t = 'hreflabel'
result = flat.flatten(loaders.xmlstr(t).load())
self.assertEqual(result, 'label')
t = 'label'
ctx = context.WovenContext()
ctx.fillSlots('href', 'href')
result = flat.flatten(flat.precompile(loaders.xmlstr(t).load()), ctx)
self.assertEqual(result, 'label')
def testHTML(self):
t = 'hreflabel'
doc = flat.flatten(loaders.htmlstr(t).load())
self.assertEqual(doc, 'label')
t = 'label'
ctx = context.WovenContext()
ctx.fillSlots('href', 'href')
precompiled = flat.precompile(loaders.htmlstr(t).load())
result = flat.flatten(precompiled, ctx)
self.assertEqual(result, 'label')