Viewing file: test_livepage.py (12.95 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
# Copyright (c) 2008 Divmod. # See LICENSE for details.
""" Tests for L{nevow.livepage}. """
from twisted.trial import unittest
from nevow import livepage, tags, util, flat, inevow, loaders, context
def makeCtx(inString=None, inAttribute=None): return livepage.JavascriptContext( isAttrib=inAttribute, inJSSingleQuoteString=inString)
class TestQuoting(unittest.TestCase): def test_normal(self): """No quoting at all happens when we are in a JavascriptContext which is not in a single quoted string or a double quoted string. """ ctx = makeCtx() self.assertEquals(flat.flatten("foo", ctx), "'foo'") self.assertEquals(flat.flatten(livepage.js("1 < 2 & 3"), ctx), "1 < 2 & 3")
def test_inAttribute(self): """When inside an attribute, we must make sure to quote double quotes. """ ctx = makeCtx(inAttribute=True) self.assertEquals(flat.flatten('foo', ctx), "'foo'") self.assertEquals( flat.flatten(livepage.js.foo('hello"world'), ctx), "foo('hello"world')") self.assertEquals( flat.flatten(livepage.js.foo("1 < 2 & 3"), ctx), "foo('1 < 2 & 3')")
def test_inSingleQuoteString(self): """When inside a single-quote string, we must quote single- quoted strings. """ ctx = makeCtx() self.assertEquals( flat.flatten(livepage.js.foo(tags.div["single'quote"]), ctx), "foo('<div>single\\'quote</div>')")
def test_rawSingleQuote(self): """When putting something returned from IQ or otherwise extracted from a docFactory inside a single-quote string, the FlattenRaw must be responsible for quoting single-quotes. """ l = loaders.stan( tags.div(pattern="foo")[ tags.a(onclick=livepage.js.foo('bar'))["click\n me"]]) self.assertEquals( flat.flatten(livepage.js.foo(inevow.IQ(l).onePattern('foo')), makeCtx()), """foo('<div><a onclick="foo(\\\'bar\\\')">click\\n me</a></div>')""")
def test_dontQuoteJS(self): """We must not put js objects in single quotes, even if they are inside another js.__call__ """ self.assertEquals( flat.flatten(livepage.js.foo(livepage.js.bar()), makeCtx()), "foo(bar())")
def sendThrough(self, what): page = livepage.LivePage() handle = livepage.ClientHandle(page, 'asdf', 0, 0) ctx = makeCtx() page.rememberStuff(ctx) d = util.Deferred() handle.setOutput(ctx, d) handle.send(what) return d.result
def test_sendThroughClientHandle(self): self.assertEquals(self.sendThrough('hello'), "'hello'") self.assertEquals(self.sendThrough(livepage.js.foo('bar',1)), "foo('bar',1)")
def test_sendThroughWithFunction(self): self.assertEquals(self.sendThrough(lambda c, d: livepage.js('hello')), 'hello') self.assertEquals(self.sendThrough(lambda c, d: [1,2, livepage.js('hi'), "it's a string"]), "12hi'it\\'s a string'")
def rend_table(self,ctx,data): return tags.table[ tags.tr[ tags.th["hea'der1"], tags.th["hea'der2"]], tags.tr(id="ro'w1")[ tags.td["va'l1"],tags.td["va'l2"]]]
self.assertEquals( self.sendThrough(livepage.append('mynode', rend_table)), """nevow_appendNode('mynode','<table><tr><th>hea\\'der1</th><th>hea\\'der2</th></tr><tr id="ro\\'w1"><td>va\\'l1</td><td>va\\'l2</td></tr></table>')""")
fakeId = '--handler-fake-id'
class TestLive(livepage.ClientHandle): sent = None def __init__(self): self.refreshInterval = 30 self.targetTimeoutCount = 3 self.timeoutCount = 0 self.handleId = 'fake-test' self.nextId = lambda: "fake-id" self.outputBuffer = [] self.closed = False self.closeNotifications = [] self.firstTime = True self.outputContext = None
def callback(self, script): self.sent = str(script)
def handleInput(self, name, *args): self.send = self.callback getattr(self, 'handle_%s' % (name, ))(self, *args) del self.send
outputConduit = property(lambda s: s, lambda s, n: None)
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) self.ctx.remember(livepage.LivePage(), inevow.IResource)
def flt(self, what, quote=False): return livepage.flt(what, quote=quote, client=self.livepage, handlerFactory=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, "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('<span />')") self.livepage.call('fun', tags.span["'"]) self.assertEquals(self.livepage.sent, r"fun('<span>\'</span>')") self.livepage.call('fun', tags.span["\""]) self.assertEquals(self.livepage.sent, "fun('<span>\"</span>')") self.livepage.call('fun', tags.span['\\']) self.assertEquals(self.livepage.sent, "fun('<span>\\\\</span>')")
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]") self.livepage.sendScript(livepage.js[()]) self.assertEquals(self.livepage.sent, "[]") 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','<span>Hello</span>')") 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 = self.flt(livepage.handler(closuredHandler)) ## The closured handler will have been assigned a unique id. self.assertEquals(result, 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): lp = self.livepage gatherer = self.livepage = LiveGatherer()
self.flt(livepage.handler(oneHandler, identifier='same')) gatherer.handleInput('--handler-same') self.assertEquals(gatherer.heard, ['one'])
self.flt(livepage.handler(twoHandler, identifier='same')) gatherer.handleInput('--handler-same') self.assertEquals(gatherer.heard, ['one', 'two'])
self.livepage = lp
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')
|