diff options
Diffstat (limited to 'tests/test_rst_compiler.py')
| -rw-r--r-- | tests/test_rst_compiler.py | 422 |
1 files changed, 192 insertions, 230 deletions
diff --git a/tests/test_rst_compiler.py b/tests/test_rst_compiler.py index 5b33db7..803fd79 100644 --- a/tests/test_rst_compiler.py +++ b/tests/test_rst_compiler.py @@ -1,253 +1,215 @@ -# coding: utf8 -# Author: Rodrigo Bistolfi -# Date: 03/2013 - +""" +Test cases for Nikola ReST extensions. -""" Test cases for Nikola ReST extensions. -A base class ReSTExtensionTestCase provides the tests basic behaviour. -Subclasses must override the "sample" class attribute with the ReST markup. -The sample will be rendered as HTML using publish_parts() by setUp(). +A sample will be rendered by CompileRest. One method is provided for checking the resulting HTML: - * assertHTMLContains(element, attributes=None, text=None) - -The HTML is parsed with lxml for checking against the data you provide. The -method takes an element argument, a string representing the *name* of an HTML -tag, like "script" or "iframe". We will try to find this tag in the document -and perform the tests on it. You can pass a dictionary to the attributes kwarg -representing the name and the value of the tag attributes. The text kwarg takes -a string argument, which will be tested against the contents of the HTML -element. -One last caveat: you need to url unquote your urls if you are going to test -attributes like "src" or "link", since the HTML rendered by docutils will be -always unquoted. + * assert_html_contains(html, element, attributes=None, text=None) """ +from io import StringIO -from __future__ import unicode_literals, absolute_import - -import os -import sys - - -import io -try: - from io import StringIO -except ImportError: - from StringIO import StringIO # NOQA -import tempfile - -import docutils -from lxml import html import pytest -import unittest +from lxml import html as lxml_html import nikola.plugins.compile.rest -from nikola.plugins.compile.rest import vimeo import nikola.plugins.compile.rest.listing -from nikola.plugins.compile.rest.doc import Plugin as DocPlugin -from nikola.utils import _reload -from .base import BaseTestCase, FakeSite, FakePost - - -class ReSTExtensionTestCase(BaseTestCase): - """ Base class for testing ReST extensions """ - - sample = 'foo' - deps = None - - def setUp(self): - self.compiler = nikola.plugins.compile.rest.CompileRest() - self.compiler.set_site(FakeSite()) - return super(ReSTExtensionTestCase, self).setUp() - - def basic_test(self): - """ Parse cls.sample into a HTML document tree """ - self.setHtmlFromRst(self.sample) - - def setHtmlFromRst(self, rst): - """ Create html output from rst string """ - tmpdir = tempfile.mkdtemp() - inf = os.path.join(tmpdir, 'inf') - outf = os.path.join(tmpdir, 'outf') - with io.open(inf, 'w+', encoding='utf8') as f: - f.write(rst) - p = FakePost('', '') - p._depfile[outf] = [] - self.compiler.site.post_per_input_file[inf] = p - self.html = self.compiler.compile_html(inf, outf) - with io.open(outf, 'r', encoding='utf8') as f: - self.html = f.read() - os.unlink(inf) - os.unlink(outf) - depfile = [p for p in p._depfile[outf] if p != outf] - depfile = '\n'.join(depfile) - if depfile: - self.assertEqual(self.deps.strip(), depfile) - os.rmdir(tmpdir) - self.html_doc = html.parse(StringIO(self.html)) - - def assertHTMLContains(self, element, attributes=None, text=None): - """ Test if HTML document includes an element with the given - attributes and text content - - """ - try: - tag = next(self.html_doc.iter(element)) - except StopIteration: - raise Exception("<{0}> not in {1}".format(element, self.html)) - else: - if attributes: - arg_attrs = set(attributes.items()) - tag_attrs = set(tag.items()) - self.assertTrue(arg_attrs.issubset(tag_attrs)) - if text: - self.assertIn(text, tag.text) - - -class ReSTExtensionTestCaseTestCase(ReSTExtensionTestCase): - """ Simple test for our base class :) """ - - sample = '.. raw:: html\n\n <iframe src="foo" height="bar">spam</iframe>' - - def test_test(self): - self.basic_test() - self.assertHTMLContains("iframe", attributes={"src": "foo"}, - text="spam") - self.assertRaises(Exception, self.assertHTMLContains, "eggs", {}) - - -class MathTestCase(ReSTExtensionTestCase): - sample = ':math:`e^{ix} = \cos x + i\sin x`' - - def test_math(self): - """ Test that math is outputting TeX code.""" - self.basic_test() - self.assertHTMLContains("span", attributes={"class": "math"}, - text="\(e^{ix} = \cos x + i\sin x\)") - +from nikola.plugins.compile.rest import vimeo +from nikola.utils import _reload, LocaleBorg -class SlidesTestCase(ReSTExtensionTestCase): - """ Slides test case """ +from .helper import FakeSite - sample = '.. slides:: IMG.jpg\n' - def test_slides(self): - """ Test the slides js generation and img tag creation """ - self.basic_test() - self.assertHTMLContains("img", attributes={"src": "IMG.jpg"}) +def test_ReST_extension(): + sample = '.. raw:: html\n\n <iframe src="foo" height="bar">spam</iframe>' + html = get_html_from_rst(sample) + + assert_html_contains(html, "iframe", attributes={"src": "foo"}, text="spam") + + with pytest.raises(Exception): + assert_html_contains("eggs", {}) + + +def test_math_extension_outputs_tex(): + """Test that math is outputting TeX code.""" + sample = r":math:`e^{ix} = \cos x + i\sin x`" + html = get_html_from_rst(sample) + + assert_html_contains( + html, + "span", + attributes={"class": "math"}, + text=r"\(e^{ix} = \cos x + i\sin x\)", + ) + + +def test_soundcloud_iframe(): + """Test SoundCloud iframe tag generation""" + + sample = ".. soundcloud:: SID\n :height: 400\n :width: 600" + html = get_html_from_rst(sample) + assert_html_contains( + html, + "iframe", + attributes={ + "src": ( + "https://w.soundcloud.com/player/" + "?url=http://api.soundcloud.com/" + "tracks/SID" + ), + "height": "400", + "width": "600", + }, + ) + + +def test_youtube_iframe(): + """Test Youtube iframe tag generation""" + + sample = ".. youtube:: YID\n :height: 400\n :width: 600" + html = get_html_from_rst(sample) + assert_html_contains( + html, + "iframe", + attributes={ + "src": ( + "https://www.youtube-nocookie.com" + "/embed/YID?rel=0&" + "wmode=transparent" + ), + "height": "400", + "width": "600", + "frameborder": "0", + "allowfullscreen": "", + "allow": "encrypted-media", + }, + ) + + +def test_vimeo(disable_vimeo_api_query): + """Test Vimeo iframe tag generation""" + + sample = ".. vimeo:: VID\n :height: 400\n :width: 600" + html = get_html_from_rst(sample) + assert_html_contains( + html, + "iframe", + attributes={ + "src": ("https://player.vimeo.com/" "video/VID"), + "height": "400", + "width": "600", + }, + ) + + +@pytest.mark.parametrize( + "sample", + [ + ".. code-block:: python\n\n import antigravity", + ".. sourcecode:: python\n\n import antigravity", + ], +) +def test_rendering_codeblock_alias(sample): + """Test CodeBlock aliases""" + get_html_from_rst(sample) + + +def test_doc_doesnt_exist(): + with pytest.raises(Exception): + assert_html_contains("anything", {}) + + +def test_doc(): + sample = "Sample for testing my :doc:`fake-post`" + html = get_html_from_rst(sample) + assert_html_contains( + html, "a", text="Fake post", attributes={"href": "/posts/fake-post"} + ) + + +def test_doc_titled(): + sample = "Sample for testing my :doc:`titled post <fake-post>`" + html = get_html_from_rst(sample) + assert_html_contains( + html, "a", text="titled post", attributes={"href": "/posts/fake-post"} + ) + + +@pytest.fixture(autouse=True, scope="module") +def localeborg_base(): + """A base config of LocaleBorg.""" + LocaleBorg.reset() + assert not LocaleBorg.initialized + LocaleBorg.initialize({}, "en") + assert LocaleBorg.initialized + assert LocaleBorg().current_lang == "en" + try: + yield + finally: + LocaleBorg.reset() + assert not LocaleBorg.initialized + + +def get_html_from_rst(rst): + """Create html output from rst string""" + + compiler = nikola.plugins.compile.rest.CompileRest() + compiler.set_site(FakeSite()) + return compiler.compile_string(rst)[0] + + +class FakePost: + def __init__(self, outfile): + self._depfile = {outfile: []} + + +def assert_html_contains(html, element, attributes=None, text=None): + """ + Test if HTML document includes an element with the given attributes + and text content. + + The HTML is parsed with lxml for checking against the data you + provide. The method takes an element argument, a string representing + the *name* of an HTML tag, like "script" or "iframe". + We will try to find this tag in the document and perform the tests + on it. You can pass a dictionary to the attributes kwarg + representing the name and the value of the tag attributes. The text + kwarg takes a string argument, which will be tested against the + contents of the HTML element. + + One last caveat: you need to url unquote your urls if you are going + to test attributes like "src" or "link", since the HTML rendered by + docutils will be always unquoted. + """ + html_doc = lxml_html.parse(StringIO(html)) + try: + tag = next(html_doc.iter(element)) + except StopIteration: + raise Exception("<{0}> not in {1}".format(element, html)) -class SoundCloudTestCase(ReSTExtensionTestCase): - """ SoundCloud test case """ + if attributes: + arg_attrs = set(attributes.items()) + tag_attrs = set(tag.items()) + assert arg_attrs.issubset(tag_attrs) - sample = '.. soundcloud:: SID\n :height: 400\n :width: 600' + if text: + assert text in tag.text - def test_soundcloud(self): - """ Test SoundCloud iframe tag generation """ - self.basic_test() - self.assertHTMLContains("iframe", - attributes={"src": ("https://w.soundcloud.com" - "/player/?url=http://" - "api.soundcloud.com/" - "tracks/SID"), - "height": "400", "width": "600"}) +@pytest.fixture +def disable_vimeo_api_query(): + """ + Disable query of the vimeo api over the wire -class VimeoTestCase(ReSTExtensionTestCase): - """Vimeo test. Set Vimeo.request_size to False for avoiding querying the Vimeo api - over the network - + over the network. """ - sample = '.. vimeo:: VID\n :height: 400\n :width: 600' - - def setUp(self): - """ Disable query of the vimeo api over the wire """ - vimeo.Vimeo.request_size = False - super(VimeoTestCase, self).setUp() + before = vimeo.Vimeo.request_size + vimeo.Vimeo.request_size = False + try: _reload(nikola.plugins.compile.rest) - - def test_vimeo(self): - """ Test Vimeo iframe tag generation """ - self.basic_test() - self.assertHTMLContains("iframe", - attributes={"src": ("https://player.vimeo.com/" - "video/VID"), - "height": "400", "width": "600"}) - - -class YoutubeTestCase(ReSTExtensionTestCase): - """ Youtube test case """ - - sample = '.. youtube:: YID\n :height: 400\n :width: 600' - - def test_youtube(self): - """ Test Youtube iframe tag generation """ - self.basic_test() - self.assertHTMLContains("iframe", - attributes={"src": ("https://www.youtube.com/" - "embed/YID?rel=0&hd=1&" - "wmode=transparent"), - "height": "400", "width": "600"}) - - -class ListingTestCase(ReSTExtensionTestCase): - """ Listing test case and CodeBlock alias tests """ - - deps = None - sample1 = '.. listing:: nikola.py python\n\n' - sample2 = '.. code-block:: python\n\n import antigravity' - sample3 = '.. sourcecode:: python\n\n import antigravity' - - # def test_listing(self): - # """ Test that we can render a file object contents without errors """ - # with cd(os.path.dirname(__file__)): - # self.deps = 'listings/nikola.py' - # self.setHtmlFromRst(self.sample1) - - def test_codeblock_alias(self): - """ Test CodeBlock aliases """ - self.deps = None - self.setHtmlFromRst(self.sample2) - self.setHtmlFromRst(self.sample3) - - -class DocTestCase(ReSTExtensionTestCase): - """ Ref role test case """ - - sample = 'Sample for testing my :doc:`doesnt-exist-post`' - sample1 = 'Sample for testing my :doc:`fake-post`' - sample2 = 'Sample for testing my :doc:`titled post <fake-post>`' - - def setUp(self): - # Initialize plugin, register role - self.plugin = DocPlugin() - self.plugin.set_site(FakeSite()) - # Hack to fix leaked state from integration tests - try: - f = docutils.parsers.rst.roles.role('doc', None, None, None)[0] - f.site = FakeSite() - except AttributeError: - pass - return super(DocTestCase, self).setUp() - - def test_doc_doesnt_exist(self): - self.assertRaises(Exception, self.assertHTMLContains, 'anything', {}) - - def test_doc(self): - self.setHtmlFromRst(self.sample1) - self.assertHTMLContains('a', - text='Fake post', - attributes={'href': '/posts/fake-post'}) - - def test_doc_titled(self): - self.setHtmlFromRst(self.sample2) - self.assertHTMLContains('a', - text='titled post', - attributes={'href': '/posts/fake-post'}) - - -if __name__ == "__main__": - unittest.main() + yield + finally: + vimeo.Vimeo.request_size = before |
