""" Tests for our nevow compatiblity layer. """ from twisted.internet import defer from twisted.web import template from twisted.web import error as twerror from twisted.web.template import tags as T from gavo.formal import nevowc from gavo.helpers import testhelpers N_NS = "http://nevow.com/ns/nevow/0.1" T_NS = "http://twistedmatrix.com/ns/twisted.web.template/0.1" def loadXML(literal, namespace=N_NS): """returns a stan tag from the XML literal. The XML literal should contain exactly one %s, which will then be filled with namespace. """ return nevowc.XMLString(literal%namespace).load()[0] class TwistedLoaderTest(testhelpers.VerboseTest): ns = T_NS def testLoadSimple(self): res = loadXML(""" """, self.ns) iEl = res.children[0] self.assertEqual(iEl.tagName, '') self.assertEqual(iEl.render, 'foo') self.assertEqual(iEl.attributes["nevow:data"], "bar") def testLoadNested(self): res = loadXML("""

yadda

""", self.ns) linkEl = res[0].children[0].children[0] self.assertEqual(linkEl.tagName, "link") self.assertEqual(linkEl.attributes["q:property"], "gack") scriptEl = res[0].children[0].children[1] self.assertEqual(scriptEl.children[0].tagName, "html:p") self.assertEqual(scriptEl.children[0].render, "x") pEl = res[0].children[1].children[0] self.assertEqual(pEl.children[0].render, "bar") def testBindNevowForbidden(self): self.assertRaisesWithMsg(Exception, "You may not bind the nevow prefix to a non-twisted or non-nevow URI", loadXML, ("""""", "http://anything.else")) class NevowLoaderTest(TwistedLoaderTest): ns = N_NS # run tests from parent class, just with the nevow namespace. class LocatePatternTest(testhelpers.VerboseTest): def testLocateBasic(self): res = loadXML("""""") baseEl = res pats = nevowc.locatePatterns(baseEl, ["item", "empty"]) self.assertEqual([p.attributes["class"] for p in pats["item"]], ["odd", "even"]) self.assertEqual([p.attributes["class"] for p in pats["empty"]], ["empty"]) def testLocateRecursiveStop(self): res = loadXML("""""") pats = nevowc.locatePatterns(res, ["item"], ["sequence"]) self.assertEqual( [p.attributes["class"] for p in pats["item"]], ["outer"]) innerUL = res.children[0].children[0] pats = nevowc.locatePatterns(innerUL, ["item"], ["sequence"]) self.assertEqual( [p.attributes["class"] for p in pats["item"]], ["inner"]) def testLocateRecursiveNoStop(self): res = loadXML("""""") pats = nevowc.locatePatterns(res, ["item"], ["random"]) self.assertEqual( [p.attributes["class"] for p in pats["item"]], ["outer", "inner"]) innerUL = res.children[0].children[0] pats = nevowc.locatePatterns(innerUL, ["item"], ["random"]) self.assertEqual( [p.attributes["class"] for p in pats["item"]], ['inner']) def renderElementSync(el, renderClass=nevowc.CommonRenderers): """returns a flattened string for el. el must not contain any deferreds, and it must not require anything from the request. """ res = [] def collect(rendered): res.append(rendered) template.flattenString(None, nevowc.elementFromTag(el, renderClass) ).addBoth(collect) if hasattr(res[0], "raiseException"): res[0].raiseException() return res[0].decode("utf-8") class RenderSequenceTest(testhelpers.VerboseTest): def testBasic(self): el = loadXML("""""", N_NS) el.slotData = list(range(2)) self.assertEqual(renderElementSync(el), '') def testDetachedRender(self): # i.e., render functions not on the item pattern el = loadXML("""""", T_NS) el.slotData = list(range(2)) self.assertEqual(renderElementSync(el), '') def testNestedRender(self): el = loadXML("""""", N_NS) el.slotData = [list(range(2)), list(range(3,5))] self.assertEqual(renderElementSync(el), '') def testMultiPattern(self): el = loadXML("""""", T_NS) el.slotData = list(range(4)) self.assertEqual(renderElementSync(el), '') def testEmpty(self): el = loadXML("""""", N_NS) el.slotData = [] self.assertEqual(renderElementSync(el), "

Nix da

") def testNone(self): el = loadXML("""""", N_NS) el.slotData = ["a", None, "b"] self.assertEqual(renderElementSync(el), "") def testMappingSequenceTest(self): el = loadXML("""""", T_NS) el.slotData = [{"von": "a", "zu": "b"},{"von": "c", "zu": "d"},] self.assertEqual(renderElementSync(el), '') class DataTricksTest(testhelpers.VerboseTest): def testLoadData(self): class B(nevowc.CommonRenderers): def data_x(self, request, tag): return 4 el = loadXML( '' '

o

', N_NS) self.assertEqual(renderElementSync(el, B), "

4

o

4

") def testIndexing(self): class B(nevowc.CommonRenderers): def data_x(self, request, tag): return ["a", "b", "c"] @template.renderer def dataAsIs(self, request, tag): return tag.slotData el = loadXML('' '

' '

', N_NS) self.assertEqual(renderElementSync(el, B), "cc") def testComputedMethod(self): class B(nevowc.CommonRenderers): def data_gen(self, arg): return lambda request, tag: arg.split() el = loadXML("""
now:
""", T_NS) self.assertEqual(renderElementSync(el, B), '
now: one
now: two
') def testInvisible(self): class B(nevowc.CommonRenderers): def data_x(self, request, tag): return ["http://foo", "foo"] el = loadXML("""""", N_NS) self.assertEqual(renderElementSync(el, B), 'foo') def testNested(self): class B(nevowc.CommonRenderers): def data_x(self, request, tag): return [None, "won", "too"] @template.renderer def ifdata(self, request, tag): if tag.slotData: return tag return "" el = loadXML("""

""", N_NS) self.assertEqual(renderElementSync(el, B), '
  • won
  • too
') def testPropagatingThroughRender(self): class B(nevowc.CommonRenderers): def data_x(self, request, tag): return ["won", "too"] @template.renderer def ifdata(self, request, tag): if tag.slotData: return tag return "" el = loadXML("""
""", N_NS) self.assertEqual(renderElementSync(el, B), '
  • won
  • too
') class RenderMappingTest(testhelpers.VerboseTest): def testBasic(self): class B(nevowc.CommonRenderers): def data_dict(self, request, tag): return [ {"term": "foo", "desc": "An expletive"}, {"term": "bar", "desc": "No expletive"},] el = loadXML( """
""", N_NS) self.assertEqual(renderElementSync(el, B), '
foo
An expletive
bar
' 'No expletive
') def testMappingSetsData(self): class B(nevowc.CommonRenderers): def data_dict(self, request, tag): return [ {"term": "foo", "desc": "An expletive"},] @template.renderer def term(self, request, tag): data = tag.slotData return tag[data["term"]] el = loadXML( """
""", N_NS) self.assertEqual(renderElementSync(el, B), '
foo
An expletive
') def testKey(self): class B(nevowc.CommonRenderers): def data_dict(self, request, tag): return {"term": "foo", "desc": "An expletive"} @template.renderer def mogrify(self, request, tag): data = tag.slotData return tag["".join(list(reversed(data)))] el = loadXML( """

Backward: and forward:

""", N_NS) self.assertEqual(renderElementSync(el, B), '

Backward: oof and forward: foo

') class RenderTricksTest(testhelpers.VerboseTest): def testComputedMethod(self): class R(nevowc.CommonRenderers): @template.renderer def gen(self, arg): def fun(request, tag): for a in arg.split(): yield tag.clone()[a] return fun el = loadXML("""
""", T_NS) self.assertEqual(renderElementSync(el, R), '
  • a
  • b
  • c
') def testNonRenderRejected(self): el = loadXML("""
    """, T_NS) # I suppose this was intended to raise UnexposedMethodError, # but the None default in element.lookupRenderMethod prevents # that right now; and then, anyway, the flattener machinery # dumbs it all down to a FlattnerError (which would be another # thing that'd be good to change. self.assertRaises(Exception, renderElementSync, el) def testRenderTwice(self): class R(nevowc.CommonRenderers): count = [1] def data_ct(self, request, tag): self.count[0] += 1 return self.count[0] el = loadXML( """

    """, T_NS) self.assertEqual(renderElementSync(el, R), '

    2

    ') self.assertEqual(renderElementSync(el, R), '

    3

    ') def testRenderTwiceRecursive(self): class R(nevowc.CommonRenderers): count = [1] def data_range(self, request, tag): self.count[0] += 1 return list(range(self.count[0])) el = loadXML( """

    """, T_NS) self.assertEqual(renderElementSync(el, R), '

    01

    ') self.assertEqual(renderElementSync(el, R), '

    012

    ') class FlattenSyncTest(testhelpers.VerboseTest): def testSimple(self): el = loadXML('

    Hello, World!

    ', T_NS) self.assertEqual(nevowc.flattenSync(el), b"

    Hello, World!

    ") def testError(self): class R(template.Element): @template.renderer def fail(self, request, tag): raise IOError("Hello, world!") loader = template.TagLoader( T.p(render="fail")["not rendered"]) self.assertRaises(twerror.FlattenerError, nevowc.flattenSync, R()) def testDeferred(self): class R(template.Element): @template.renderer def fire(self, request, tag): d = defer.Deferred() return d loader = template.TagLoader( T.p(render="fire")["not rendered"]) self.assertRaisesWithMsg(NotImplementedError, "flattenSync cannot deal with elements containing deferreds.", nevowc.flattenSync, (R(),)) def testWithData(self): class R(nevowc.NevowcElement): def data_foo(self, request, tag): return [{"a": "foo", "b": "bar"}, {"a": "hui", "b": "buh"}] loader = template.TagLoader( nevowc.addNevowAttributes(T.div, data="foo")[ T.ul(render="sequence")[ nevowc.addNevowAttributes(T.li(render="mapping"), pattern="item")[ template.slot("a"), " x ", template.slot("b")]]]) self.assertEqual(nevowc.flattenSync(R()), b'
    • foo x bar
    • hui x buh
    ') if __name__=="__main__": testhelpers.main(RenderSequenceTest)