/usr/lib/python3/dist-packages/twisted/web/test/test_template.py (28841B)
Hello, world.
" """ Simple template to use to exercise the loaders. """ def loaderFactory(self) -> ITemplateLoader: raise NotImplementedError def test_load(self) -> None: """ Verify that the loader returns a tag with the correct children. """ assert isinstance(self, TestCase) loader = self.loaderFactory() (tag,) = loader.load() assert isinstance(tag, Tag) warnings = self.flushWarnings(offendingFunctions=[self.loaderFactory]) if self.deprecatedUse: self.assertEqual(len(warnings), 1) self.assertEqual(warnings[0]["category"], DeprecationWarning) self.assertEqual( warnings[0]["message"], "Passing filenames or file objects to XMLFile is " "deprecated since Twisted 12.1. Pass a FilePath instead.", ) else: self.assertEqual(len(warnings), 0) self.assertEqual(tag.tagName, "p") self.assertEqual(tag.children, ["Hello, world."]) def test_loadTwice(self) -> None: """ If {load()} can be called on a loader twice the result should be the same. """ assert isinstance(self, TestCase) loader = self.loaderFactory() tags1 = loader.load() tags2 = loader.load() self.assertEqual(tags1, tags2) test_loadTwice.suppress = [_xmlFileSuppress] # type: ignore[attr-defined] class XMLStringLoaderTests(TestCase, XMLLoaderTestsMixin): """ Tests for L{twisted.web.template.XMLString} """ deprecatedUse = False def loaderFactory(self) -> ITemplateLoader: """ @return: an L{XMLString} constructed with C{self.templateString}. """ return XMLString(self.templateString) class XMLFileWithFilePathTests(TestCase, XMLLoaderTestsMixin): """ Tests for L{twisted.web.template.XMLFile}'s L{FilePath} support. """ deprecatedUse = False def loaderFactory(self) -> ITemplateLoader: """ @return: an L{XMLString} constructed with a L{FilePath} pointing to a file that contains C{self.templateString}. """ fp = FilePath(self.mktemp()) fp.setContent(self.templateString.encode("utf8")) return XMLFile(fp) class XMLFileWithFileTests(TestCase, XMLLoaderTestsMixin): """ Tests for L{twisted.web.template.XMLFile}'s deprecated file object support. """ deprecatedUse = True def loaderFactory(self) -> ITemplateLoader: """ @return: an L{XMLString} constructed with a file object that contains C{self.templateString}. """ return XMLFile(StringIO(self.templateString)) # type: ignore[arg-type] class XMLFileWithFilenameTests(TestCase, XMLLoaderTestsMixin): """ Tests for L{twisted.web.template.XMLFile}'s deprecated filename support. """ deprecatedUse = True def loaderFactory(self) -> ITemplateLoader: """ @return: an L{XMLString} constructed with a filename that points to a file containing C{self.templateString}. """ fp = FilePath(self.mktemp()) fp.setContent(self.templateString.encode("utf8")) return XMLFile(fp.path) # type: ignore[arg-type] class FlattenIntegrationTests(FlattenTestCase): """ Tests for integration between L{Element} and L{twisted.web._flatten.flatten}. """ def test_roundTrip(self) -> None: """ Given a series of parsable XML strings, verify that L{twisted.web._flatten.flatten} will flatten the L{Element} back to the input when sent on a round trip. """ fragments = [ b"Hello, world.
", b"", b"", b'\xe2\x98\x83
", ] for xml in fragments: self.assertFlattensImmediately(Element(loader=XMLString(xml)), xml) def test_entityConversion(self) -> None: """ When flattening an HTML entity, it should flatten out to the utf-8 representation if possible. """ element = Element(loader=XMLString("☃
")) self.assertFlattensImmediately(element, b"\xe2\x98\x83
") def test_missingTemplateLoader(self) -> None: """ Rendering an Element without a loader attribute raises the appropriate exception. """ self.assertFlatteningRaises(Element(), MissingTemplateLoader) def test_missingRenderMethod(self) -> None: """ Flattening an L{Element} with a C{loader} which has a tag with a render directive fails with L{FlattenerError} if there is no available render method to satisfy that directive. """ element = Element( loader=XMLString( """ """ ) ) self.assertFlatteningRaises(element, MissingRenderMethod) def test_transparentRendering(self) -> None: """ A C{transparent} element should be eliminated from the DOM and rendered as only its children. """ element = Element( loader=XMLString( "Goodbye, world.
""" ) ) self.assertFlattensImmediately(element, b"Hello, world.") def test_loaderClassAttribute(self) -> None: """ If there is a non-None loader attribute on the class of an Element instance but none on the instance itself, the class attribute is used. """ class SubElement(Element): loader = XMLString("Hello, world.
") self.assertFlattensImmediately(SubElement(), b"Hello, world.
") def test_directiveRendering(self) -> None: """ An Element with a valid render directive has that directive invoked and the result added to the output. """ renders = [] class RenderfulElement(Element): @renderer def renderMethod( self, request: Optional[IRequest], tag: Tag ) -> Flattenable: renders.append((self, request)) return tag("Hello, world.") element = RenderfulElement( loader=XMLString( """ """ ) ) self.assertFlattensImmediately(element, b"Hello, world.
") def test_directiveRenderingOmittingTag(self) -> None: """ An Element with a render method which omits the containing tag successfully removes that tag from the output. """ class RenderfulElement(Element): @renderer def renderMethod( self, request: Optional[IRequest], tag: Tag ) -> Flattenable: return "Hello, world." element = RenderfulElement( loader=XMLString( """Goodbye, world.
""" ) ) self.assertFlattensImmediately(element, b"Hello, world.") def test_elementContainingStaticElement(self) -> None: """ An Element which is returned by the render method of another Element is rendered properly. """ class RenderfulElement(Element): @renderer def renderMethod( self, request: Optional[IRequest], tag: Tag ) -> Flattenable: return tag(Element(loader=XMLString("Hello, world."))) element = RenderfulElement( loader=XMLString( """ """ ) ) self.assertFlattensImmediately(element, b"Hello, world.
") def test_elementUsingSlots(self) -> None: """ An Element which is returned by the render method of another Element is rendered properly. """ class RenderfulElement(Element): @renderer def renderMethod( self, request: Optional[IRequest], tag: Tag ) -> Flattenable: return tag.fillSlots(test2="world.") element = RenderfulElement( loader=XMLString( ''
'
Hello, world.
") def test_elementContainingDynamicElement(self) -> None: """ Directives in the document factory of an Element returned from a render method of another Element are satisfied from the correct object: the "inner" Element. """ class OuterElement(Element): @renderer def outerMethod(self, request: Optional[IRequest], tag: Tag) -> Flattenable: return tag( InnerElement( loader=XMLString( """Hello, world.
") def test_sameLoaderTwice(self) -> None: """ Rendering the output of a loader, or even the same element, should return different output each time. """ sharedLoader = XMLString( ''
'
1 1
") self.assertFlattensImmediately(e1, b"2 2
") self.assertFlattensImmediately(e2, b"3 1
") class TagLoaderTests(FlattenTestCase): """ Tests for L{TagLoader}. """ def setUp(self) -> None: self.loader = TagLoader(tags.i("test")) def test_interface(self) -> None: """ An instance of L{TagLoader} provides L{ITemplateLoader}. """ self.assertTrue(verifyObject(ITemplateLoader, self.loader)) def test_loadsList(self) -> None: """ L{TagLoader.load} returns a list, per L{ITemplateLoader}. """ self.assertIsInstance(self.loader.load(), list) def test_flatten(self) -> None: """ L{TagLoader} can be used in an L{Element}, and flattens as the tag used to construct the L{TagLoader} would flatten. """ e = Element(self.loader) self.assertFlattensImmediately(e, b"test") class TestElement(Element): """ An L{Element} that can be rendered successfully. """ loader = XMLString( '' "Hello, world." "
" ) class TestFailureElement(Element): """ An L{Element} that can be used in place of L{FailureElement} to verify that L{renderElement} can render failures properly. """ loader = XMLString( '' "I failed." "
" ) def __init__(self, failure: Failure, loader: object = None): self.failure = failure class FailingElement(Element): """ An element that raises an exception when rendered. """ def render(self, request: Optional[IRequest]) -> "Flattenable": a = 42 b = 0 return f"{a // b}" class FakeSite: """ A minimal L{Site} object that we can use to test displayTracebacks """ displayTracebacks = False @implementer(IRequest) class DummyRenderRequest(DummyRequest): # type: ignore[misc] """ A dummy request object that has a C{site} attribute. This does not implement the full IRequest interface, but enough of it for this test suite. """ def __init__(self) -> None: super().__init__([""]) self.site = FakeSite() class RenderElementTests(TestCase): """ Test L{renderElement} """ def setUp(self) -> None: """ Set up a common L{DummyRenderRequest}. """ self.request = DummyRenderRequest() def test_simpleRender(self) -> Deferred[None]: """ L{renderElement} returns NOT_DONE_YET and eventually writes the rendered L{Element} to the request before finishing the request. """ element = TestElement() d = self.request.notifyFinish() def check(_: object) -> None: self.assertEqual( b"".join(self.request.written), b"\n" b"Hello, world.
", ) self.assertTrue(self.request.finished) d.addCallback(check) self.assertIdentical(NOT_DONE_YET, renderElement(self.request, element)) return d def test_simpleFailure(self) -> Deferred[None]: """ L{renderElement} handles failures by writing a minimal error message to the request and finishing it. """ element = FailingElement() d = self.request.notifyFinish() def check(_: object) -> None: flushed = self.flushLoggedErrors(FlattenerError) self.assertEqual(len(flushed), 1) self.assertEqual( b"".join(self.request.written), ( b"\n" b'I failed.
" ) self.assertTrue(self.request.finished) d.addCallback(check) renderElement(self.request, element, _failElement=TestFailureElement) return d def test_nonDefaultDoctype(self) -> Deferred[None]: """ L{renderElement} will write the doctype string specified by the doctype keyword argument. """ element = TestElement() d = self.request.notifyFinish() def check(_: object) -> None: self.assertEqual( b"".join(self.request.written), ( b'\n' b"Hello, world.
" ), ) d.addCallback(check) renderElement( self.request, element, doctype=( b'' ), ) return d def test_noneDoctype(self) -> Deferred[None]: """ L{renderElement} will not write out a doctype if the doctype keyword argument is L{None}. """ element = TestElement() d = self.request.notifyFinish() def check(_: object) -> None: self.assertEqual(b"".join(self.request.written), b"Hello, world.
") d.addCallback(check) renderElement(self.request, element, doctype=None) return d