from twisted.trial import unittest
from nevow import livepage, tags, context, events, util
fakeId = 'fake-id'
class TestLive(livepage.ClientHandle):
def __init__(self):
self.refreshInterval = 30
self.targetTimeoutCount = 3
self.timeoutCount = 0
self.handleId = 'fake-test'
self.events = events.EventNotification()
self.events.nextId = lambda: fakeId
self.outputBuffer = []
self.closed = False
self.closeNotifications = []
self.firstTime = True
def sendScript(self, script):
self.sent = str(script)
class LiveGatherer(TestLive):
def __init__(self):
TestLive.__init__(self)
self.heard = []
def sendScript(self, script):
self.heard.append(script)
class Quoting(unittest.TestCase):
def setUp(self):
self.livepage = TestLive()
self.ctx = context.WovenContext()
self.ctx.remember(self.livepage, livepage.IClientHandle)
def flt(self, what):
return livepage.flt(what, quote=False, client=self.livepage)
def testCall(self):
self.livepage.call("concat", "1", "2")
self.assertEquals(self.livepage.sent, "concat('1','2');")
self.livepage.call("bloop", r"a\b\c")
self.assertEquals(self.livepage.sent, r"bloop('a\\b\\c');")
self.livepage.call("zoop", "a'b'c")
self.assertEquals(self.livepage.sent, r"zoop('a\'b\'c');")
self.livepage.call("floop", "a\nb\nc")
self.assertEquals(self.livepage.sent, r"floop('a\nb\nc');")
def test_callWithJS(self):
self.livepage.call("add", 1, 2)
self.assertEquals(self.livepage.sent, "add(1,2);")
self.livepage.call("amIEvil", True)
self.assertEquals(self.livepage.sent, "amIEvil(true);")
self.livepage.call("add", 1.4, 2.4)
self.assertEquals(self.livepage.sent, "add(1.4,2.4);")
self.livepage.call('alert', livepage.js('document.title'))
self.assertEquals(self.livepage.sent, 'alert(document.title);')
self.livepage.call('alert', livepage.document.title)
self.assertEquals(self.livepage.sent, 'alert(document.title);')
def test_callWithStan(self):
self.livepage.call("replace", tags.span)
self.assertEquals(self.livepage.sent, "replace('');")
self.livepage.call('fun', tags.span["'"])
self.assertEquals(self.livepage.sent, r"fun('\'');")
self.livepage.call('fun', tags.span["\""])
self.assertEquals(self.livepage.sent, "fun('\"');")
self.livepage.call('fun', tags.span["\\"])
self.assertEquals(self.livepage.sent, r"fun('\\');")
def test_js(self):
foo = livepage.js('foo')
self.livepage.call('alert', foo('1'))
self.assertEquals(self.livepage.sent, "alert(foo('1'));")
self.livepage.sendScript(foo(1))
self.assertEquals(self.livepage.sent, "foo(1)")
window = livepage.js('window')
self.livepage.sendScript(window.open('http://google.com'))
self.assertEquals(self.livepage.sent, "window.open('http://google.com')")
array = livepage.js('array')
self.livepage.sendScript(array[5])
self.assertEquals(self.livepage.sent, "array[5]")
self.livepage.sendScript(livepage.js[1,2,3])
self.assertEquals(self.livepage.sent, "[1,2,3]")
def test_setAndAppend(self):
for apiName in ['set', 'append']:
api = getattr(self.livepage, apiName)
funcName = "nevow_%sNode" % (apiName, )
api('node', 'value')
self.assertEquals(self.livepage.sent, funcName + "('node', 'value');")
api('node', 1)
self.assertEquals(self.livepage.sent, funcName + "('node', '1');")
api('node', tags.span["Hello"])
self.assertEquals(self.livepage.sent, funcName + "('node', 'Hello');")
api('node', livepage.document.title)
self.assertEquals(self.livepage.sent, funcName + "('node', document.title);")
api('node', '\\')
self.assertEquals(self.livepage.sent, funcName + r"('node', '\\');")
api('node', "'")
self.assertEquals(self.livepage.sent, funcName + r"('node', '\'');")
api('node', '"')
self.assertEquals(self.livepage.sent, funcName + "('node', '\"');")
api('\\', '')
self.assertEquals(self.livepage.sent, funcName + "('\\\\', '');")
def test_alert(self):
self.livepage.alert('Hello')
self.assertEquals(self.livepage.sent, "alert('Hello');")
self.livepage.alert(5)
self.assertEquals(self.livepage.sent, "alert('5');")
self.livepage.alert(livepage.document.title)
self.assertEquals(self.livepage.sent, "alert(document.title);")
self.livepage.alert('\\')
self.assertEquals(self.livepage.sent, "alert('\\\\');")
self.livepage.alert("'")
self.assertEquals(self.livepage.sent, r"alert('\'');")
self.livepage.alert('"')
self.assertEquals(self.livepage.sent, "alert('\"');")
def test_handler(self):
result = livepage.handler(onClick)
self.assertEquals(self.flt(result),
livepage.ctsTemplate % (fakeId, '', livepage.handledEventPostlude))
self.livepage.handleInput(fakeId)
self.assertEquals(self.livepage.sent, 'null;')
def test_closedOverHandler(self):
closedOver = 'hello'
def closuredHandler(client):
client.sendScript(closedOver)
## We have to "render" the result because the event handler has to be
## subscribed to at render time.
result = livepage.handler(closuredHandler)(self.ctx, None)
## The closured handler will have been assigned a unique id.
self.assertEquals(result.content,
livepage.ctsTemplate % (fakeId, '', livepage.handledEventPostlude))
self.livepage.handleInput(fakeId)
self.assertEquals(self.livepage.sent, 'hello')
def test_handlerWithArgs(self):
options = [
dict(bubble=True, outsideAttribute=True),
dict(bubble=False, outsideAttribute=True),
dict(bubble=False, outsideAttribute=False),
dict(bubble=True, outsideAttribute=False)]
for opts in options:
if opts['bubble']:
postlude = ''
else:
postlude = livepage.handledEventPostlude
self.assertEquals(
self.flt(livepage.handler(argsHandler, 'hello', **opts)),
livepage.ctsTemplate % (fakeId, ",'hello'", postlude))
self.assertEquals(
self.flt(livepage.handler(argsHandler, "'", **opts)),
livepage.ctsTemplate % (fakeId, ",'\\''", postlude))
self.assertEquals(
self.flt(livepage.handler(argsHandler, "\\", **opts)),
livepage.ctsTemplate % (fakeId, ",'\\\\'", postlude))
self.assertEquals(
self.flt(livepage.handler(argsHandler, "\n", **opts)),
livepage.ctsTemplate % (fakeId, ",'\\n'", postlude))
def test_handlerWithArgsQuoting(self):
self.assertEquals(
self.flt(livepage.handler(argsHandler, '"')),
livepage.ctsTemplate % (fakeId, ",'"'", livepage.handledEventPostlude))
self.assertEquals(
self.flt(livepage.handler(argsHandler, '&')),
livepage.ctsTemplate % (fakeId, ",'&'", livepage.handledEventPostlude))
def test_outsideAttributeArgsQuoting(self):
self.assertEquals(
self.flt( livepage.handler(argsHandler, '"', outsideAttribute=True)),
livepage.ctsTemplate % (fakeId, ",'\"'", livepage.handledEventPostlude))
self.assertEquals(
self.flt(livepage.handler(argsHandler, '&', outsideAttribute=True)),
livepage.ctsTemplate % (fakeId, ",'&'", livepage.handledEventPostlude))
def test_bubble(self):
self.assertEquals(
self.flt(livepage.handler(onClick, bubble=True)),
livepage.ctsTemplate % (fakeId, '', ''))
def test_handlerWithIdentifier(self):
gatherer = LiveGatherer()
ctx = context.WovenContext()
ctx.remember(gatherer, livepage.IClientHandle)
oneQual = util.qual(oneHandler)
twoQual = util.qual(twoHandler)
## Subscribe both handlers to the same identifier
livepage.handler(oneHandler, identifier='same')(ctx, None)
livepage.handler(twoHandler, identifier='same')(ctx, None)
gatherer.handleInput('same')
self.assertEquals(gatherer.heard, ['one', 'two'])
def test_decoratorLike(self):
decorator = livepage.handler(livepage.document)
self.assertEquals(
self.flt(decorator(argsHandler)),
livepage.ctsTemplate % (fakeId, ',document', livepage.handledEventPostlude))
def onClick(client):
client.sendScript('null;')
def argsHandler(client, *args):
client.sendScript(','.join(args))
def oneHandler(client):
client.sendScript('one')
def twoHandler(client):
client.sendScript('two')