# Copyright (c) 2004 Divmod.
# See LICENSE for details.
from __future__ import generators
from twisted.internet import defer
from nevow import stan
from nevow import context
from nevow import tags
from nevow import entities
from nevow import inevow
from nevow import flat
from nevow import rend
from nevow import compy
from nevow.testutil import FakeRequest, TestCase
proto = stan.Proto('hello')
class Base(TestCase):
contextFactory = context.WovenContext
def renderer(self, context, data):
return lambda context, data: ""
def setupContext(self, precompile=False, setupRequest=lambda r:r):
fr = setupRequest(FakeRequest())
ctx = context.RequestContext(tag=fr)
ctx.remember(fr, inevow.IRequest)
ctx.remember(None, inevow.IData)
ctx = context.WovenContext(parent=ctx, precompile=precompile)
return ctx
def render(self, tag, precompile=False, data=None, setupRequest=lambda r: r, setupContext=lambda c:c):
ctx = self.setupContext(precompile, setupRequest)
ctx = setupContext(ctx)
if precompile:
return flat.precompile(tag, ctx)
else:
try:
from twisted.trial import util
from nevow.flat import twist
except ImportError:
return flat.flatten(tag, ctx)
else:
L = []
util.deferredResult(twist.deferflatten(tag, ctx, L.append))
return ''.join(L)
class TestSimpleSerialization(Base):
def test_serializeProto(self):
self.assertEquals(self.render(proto), '')
def test_serializeTag(self):
tag = proto(someAttribute="someValue")
self.assertEquals(self.render(tag), '')
def test_serializeChildren(self):
tag = proto(someAttribute="someValue")[
proto
]
self.assertEquals(self.render(tag), '')
def test_serializeWithData(self):
tag = proto(data=5)
self.assertEquals(self.render(tag), '')
def test_adaptRenderer(self):
## This is an implementation of the "adapt" renderer
def _(context, data):
return context.tag[
data
]
tag = proto(data=5, render=_)
self.assertEquals(self.render(tag), '5')
def test_serializeDataWithRenderer(self):
tag = proto(data=5, render=str)
self.assertEquals(self.render(tag), '5')
def test_noContextRenderer(self):
def _(data):
return data
tag = proto(data=5, render=_)
self.assertEquals(self.render(tag), '5')
tag = proto(data=5, render=lambda data: data)
self.assertEquals(self.render(tag), '5')
def test_aBunchOfChildren(self):
tag = proto[
"A Child",
5,
"A friend in need is a friend indeed"
]
self.assertEquals(self.render(tag), 'A Child5A friend in need is a friend indeed')
def test_basicPythonTypes(self):
tag = proto(data=5)[
"A string; ",
u"A unicode string; ",
5, " (An integer) ",
1.0, " (A float) ",
1L, " (A long) ",
True, " (A bool) ",
["A ", "List; "],
stan.xml(" Some xml; "),
lambda data: "A function"
]
if self.hasBools:
self.assertEquals(self.render(tag), "A string; A unicode string; 5 (An integer) 1.0 (A float) 1 (A long) True (A bool) A List; Some xml; A function")
else:
self.assertEquals(self.render(tag), "A string; A unicode string; 5 (An integer) 1.0 (A float) 1 (A long) 1 (A bool) A List; Some xml; A function")
def test_escaping(self):
tag = proto(foo="<>&\"'")["<>&\"'"]
self.assertEquals(self.render(tag), '<>&"\'')
class TestComplexSerialization(Base):
def test_precompileWithRenderer(self):
tag = tags.html[
tags.body[
tags.div[
tags.p["Here's a string"],
tags.p(data=5, render=str)
]
]
]
prelude, context, postlude = self.render(tag, precompile=True)
self.assertEquals(prelude, "
')
def test_precompileSlotData(self):
"""Test that tags with slotData are not precompiled out of the
stan tree.
"""
tag = tags.p[tags.slot('foo')]
tag.fillSlots('foo', 'bar')
precompiled = self.render(tag, precompile=True)
self.assertEquals(self.render(precompiled), '
')
class TestMultipleRenderWithDirective(Base):
def test_it(self):
class Cool(object):
def __init__(self):
self.counter = 0
def count(self, context, data):
self.counter += 1
return self.counter
it = Cool()
tag = tags.html(data={'counter': it.count})[
tags.invisible(data=tags.directive('counter'))[
str
]
]
precompiled = self.render(tag, precompile=True)
val = self.render(precompiled)
self.assertSubstring('1', val)
val2 = self.render(precompiled)
self.assertSubstring('2', val2)
class TestEntity(Base):
def test_it(self):
val = self.render(entities.nbsp)
self.assertEquals(val, ' ')
def test_nested(self):
val = self.render(tags.html(src=entities.quot)[entities.amp])
self.assertEquals(val, '&')
def test_xml(self):
val = self.render([entities.lt, entities.amp, entities.gt])
self.assertEquals(val, '<&>')
class TestNoneAttribute(Base):
def test_simple(self):
val = self.render(tags.html(foo=None)["Bar"])
self.assertEquals(val, "Bar")
def test_slot(self):
val = self.render(tags.html().fillSlots('bar', None)(foo=tags.slot('bar'))["Bar"])
self.assertEquals(val, "Bar")
test_slot.todo = "We need to be able to roll back time in order to not output the attribute name"
class TestKey(Base):
def test_nested(self):
val = []
def appendKey(ctx, data):
val.append(ctx.key)
return ctx.tag
self.render(
tags.div(key="one", render=appendKey)[
tags.div(key="two", render=appendKey)[
tags.div(render=appendKey)[
tags.div(key="four", render=appendKey)]]])
self.assertEquals(val, ["one", "one.two", "one.two", "one.two.four"])