diff options
| author | 2013-05-30 17:41:06 -0300 | |
|---|---|---|
| committer | 2013-05-30 17:41:06 -0300 | |
| commit | 0c4dfdec5b55b6064dccc38bbfb0a7c0699c895a (patch) | |
| tree | a6707225ccc559f7edf50ddd3fdc7fc85145c921 /tests | |
| parent | 8b14a1e5b2ca574fdd4fd2377567ec98a110d4b6 (diff) | |
Imported Upstream version 5.4.4
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/base.py | 58 | ||||
| -rw-r--r-- | tests/test_compile_markdown.py | 122 | ||||
| -rw-r--r-- | tests/test_integration.py | 49 | ||||
| -rw-r--r-- | tests/test_plugin_importing.py | 6 | ||||
| -rw-r--r-- | tests/test_rst_extensions.py | 223 |
5 files changed, 455 insertions, 3 deletions
diff --git a/tests/base.py b/tests/base.py new file mode 100644 index 0000000..92576c7 --- /dev/null +++ b/tests/base.py @@ -0,0 +1,58 @@ +# coding: utf8 +# Author: Rodrigo Bistolfi +# Date: 03/2013 + + +""" Base class for Nikola test cases """ + + +__all__ = ["BaseTestCase"] + + +import sys +import unittest + + +if sys.version_info < (2, 7): + + try: + import unittest2 + _unittest2 = True + except ImportError: + _unittest2 = False + + if _unittest2: + BaseTestCase = unittest2.TestCase + + else: + + class BaseTestCase(unittest.TestCase): + """ Base class for providing 2.6 compatibility """ + + def assertIs(self, first, second, msg=None): + self.assertTrue(first is second) + + def assertIsNot(self, first, second, msg=None): + self.assertTrue(first is not second) + + def assertIsNone(self, expr, msg=None): + self.assertTrue(expr is None) + + def assertIsNotNone(self, expr, msg=None): + self.assertTrue(expr is not None) + + def assertIn(self, first, second, msg=None): + self.assertTrue(first in second) + + def assertNotIn(self, first, second, msg=None): + self.assertTrue(first not in second) + + def assertIsInstance(self, obj, cls, msg=None): + self.assertTrue(isinstance(obj, cls)) + + def assertNotIsInstance(self, obj, cls, msg=None): + self.assertFalse(isinstance(obj, cls)) + + +else: + BaseTestCase = unittest.TestCase diff --git a/tests/test_compile_markdown.py b/tests/test_compile_markdown.py new file mode 100644 index 0000000..a1f8591 --- /dev/null +++ b/tests/test_compile_markdown.py @@ -0,0 +1,122 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals +import codecs +import shutil +import tempfile +import unittest +from os import path + +from nikola.plugins.compile_markdown import CompileMarkdown + + +class CompileMarkdownTests(unittest.TestCase): + def setUp(self): + self.tmp_dir = tempfile.mkdtemp() + self.input_path = path.join(self.tmp_dir, 'input.markdown') + self.output_path = path.join(self.tmp_dir, 'output.html') + + self.compiler = CompileMarkdown() + + def compile(self, input_string): + with codecs.open(self.input_path, "w+", "utf8") as input_file: + input_file.write(input_string) + + self.compiler.compile_html(self.input_path, self.output_path) + + output_str = None + with codecs.open(self.output_path, "r", "utf8") as output_path: + output_str = output_path.read() + + return output_str + + def tearDown(self): + shutil.rmtree(self.tmp_dir) + + def test_compile_html_empty(self): + input_str = '' + actual_output = self.compile(input_str) + self.assertEquals(actual_output, '') + + def test_compile_html_heading_tags(self): + input_str = '''\ +# header 1 +## header 2 +### header 3 +#### header 4 +##### header 5 +###### header 6 +''' + expected_output = '''\ +<h2>header 1</h2> +<h3>header 2</h3> +<h4>header 3</h4> +<h5>header 4</h5> +<h6>header 5</h6> +<h7>header 6</h7> +''' + + actual_output = self.compile(input_str) + self.assertEquals(actual_output.strip(), expected_output.strip()) + + def test_compile_html_code_hilite(self): + input_str = '''\ + #!python + from this +''' + expected_output = '''\ +<table class="codehilitetable"><tr><td class="linenos">\ +<div class="linenodiv"><pre>1</pre></div>\ +</td><td class="code"><div class="code">\ +<pre><span class="kn">from</span> <span class="nn">this</span> +</pre></div> +</td></tr></table> +''' + + actual_output = self.compile(input_str) + self.assertEquals(actual_output.strip(), expected_output.strip()) + + def test_compile_html_gist(self): + input_str = '''\ +Here's a gist file inline: +[:gist: 4747847 zen.py] + +Cool, eh? +''' + expected_output = '''\ +<p>Here's a gist file inline: +<div class="gist"> +<script src="https://gist.github.com/4747847.js?file=zen.py"></script> +<noscript> +<pre>import this</pre> +</noscript> +</div> +</p> +<p>Cool, eh?</p> +''' + actual_output = self.compile(input_str) + self.assertEquals(actual_output.strip(), expected_output.strip()) + + def test_compile_html_gist_2(self): + input_str = '''\ +Here's a gist file inline, using reStructuredText syntax: +..gist:: 4747847 zen.py + +Cool, eh? +''' + expected_output = '''\ +<p>Here's a gist file inline, using reStructuredText syntax: +<div class="gist"> +<script src="https://gist.github.com/4747847.js?file=zen.py"></script> +<noscript> +<pre>import this</pre> +</noscript> +</div> +</p> +<p>Cool, eh?</p> +''' + actual_output = self.compile(input_str) + self.assertEquals(actual_output.strip(), expected_output.strip()) + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/test_integration.py b/tests/test_integration.py index c940a07..802dcc7 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -3,12 +3,15 @@ from __future__ import unicode_literals, print_function import codecs from contextlib import contextmanager +import locale import os import shutil +import subprocess # NOQA import tempfile import unittest import lxml.html +from nose.plugins.skip import SkipTest from context import nikola from nikola import main @@ -66,6 +69,7 @@ class EmptyBuildTest(unittest.TestCase): @classmethod def tearDownClass(self): """Remove the demo site.""" + shutil.rmtree(self.tmpdir) def test_build(self): """Ensure the build did something.""" @@ -82,6 +86,13 @@ class DemoBuildTest(EmptyBuildTest): """Fill the site with demo content.""" self.init_command.copy_sample_site(self.target_dir) self.init_command.create_configuration(self.target_dir) + # File for Issue #374 (empty post text) + with codecs.open(os.path.join(self.target_dir, 'posts', 'empty.txt'), "wb+", "utf8") as outf: + outf.write( + ".. title: foobar\n" + ".. slug: foobar\n" + ".. date: 2013/03/06 19:08:15\n" + ) class TranslatedBuildTest(EmptyBuildTest): @@ -89,6 +100,13 @@ class TranslatedBuildTest(EmptyBuildTest): dataname = "translated_titles" + def __init__(self, *a, **kw): + super(TranslatedBuildTest, self).__init__(*a, **kw) + try: + locale.setlocale(locale.LC_ALL, ("es", "utf8")) + except: + raise SkipTest + def test_translated_titles(self): """Check that translated title is picked up.""" en_file = os.path.join(self.target_dir, "output", "stories", "1.html") @@ -134,6 +152,37 @@ class RelativeLinkTest(DemoBuildTest): self.assertTrue(flag) +#class TestCheck(DemoBuildTest): + #"""The demo build should pass 'nikola check'""" + + #def test_check_links(self): + #with cd(self.target_dir): + #r = subprocess.call("nikola check -l", shell=True) + #self.assertEqual(r, 0) + + #def test_check_files(self): + #with cd(self.target_dir): + #r = subprocess.call("nikola check -f", shell=True) + #self.assertEqual(r, 0) + + +#class TestCheckFailure(DemoBuildTest): + #"""The demo build should pass 'nikola check'""" + + #def test_check_links_fail(self): + #with cd(self.target_dir): + #os.unlink(os.path.join("output", "archive.html")) + #rv = subprocess.call("nikola check -l", shell=True) + #self.assertEqual(rv, 1) + + #def test_check_files_fail(self): + #with cd(self.target_dir): + #with codecs.open(os.path.join("output", "foobar"), "wb+", "utf8") as outf: + #outf.write("foo") + #rv = subprocess.call("nikola check -f", shell=True) + #self.assertEqual(rv, 1) + + class RelativeLinkTest2(DemoBuildTest): """Check that dropping stories to the root doesn't break links.""" diff --git a/tests/test_plugin_importing.py b/tests/test_plugin_importing.py index 1a610bf..677dde8 100644 --- a/tests/test_plugin_importing.py +++ b/tests/test_plugin_importing.py @@ -9,8 +9,8 @@ class ImportPluginsTest(unittest.TestCase): def test_importing_command_import_wordpress(self): import nikola.plugins.command_import_wordpress # NOQA - def test_importing_task_sitemap(self): - import nikola.plugins.task_sitemap.sitemap_gen # NOQA - def test_importing_compile_rest(self): import nikola.plugins.compile_rest # NOQA + + def test_importing_plugin_compile_markdown(self): + import nikola.plugins.compile_markdown # NOQA diff --git a/tests/test_rst_extensions.py b/tests/test_rst_extensions.py new file mode 100644 index 0000000..845d6a7 --- /dev/null +++ b/tests/test_rst_extensions.py @@ -0,0 +1,223 @@ +# coding: utf8 +# Author: Rodrigo Bistolfi +# Date: 03/2013 + + +""" Test cases for Nikola ReST extensions. +A base class ReSTExtensionTestCase provides the tests basic behaivor. +Subclasses must override the "sample" class attribute with the ReST markup. +The sample will be rendered as HTML using publish_parts() by setUp(). +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. + +""" + + +from __future__ import unicode_literals + +try: + from io import StringIO +except ImportError: + from StringIO import StringIO # NOQA + +from docutils.core import publish_parts +from lxml import html +import mock + +import unittest +import nikola.plugins.compile_rest +from nikola.utils import _reload +from base import BaseTestCase + + +class ReSTExtensionTestCase(BaseTestCase): + """ Base class for testing ReST extensions """ + + sample = None + + def setUp(self): + """ Parse cls.sample into a HTML document tree """ + super(ReSTExtensionTestCase, self).setUp() + self.setHtmlFromRst(self.sample) + + def setHtmlFromRst(self, rst): + """ Create html output from rst string """ + self.html = publish_parts(rst, writer_name="html")["body"] + 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("<{}> not in {}".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.assertHTMLContains("iframe", attributes={"src": "foo"}, + text="spam") + self.assertRaises(Exception, self.assertHTMLContains, "eggs", {}) + + +class GistTestCase(ReSTExtensionTestCase): + """ Test GitHubGist. + We will replace get_raw_gist() and get_raw_gist_with_filename() + monkeypatching the GitHubGist class for avoiding network dependency + + """ + gist_type = nikola.plugins.compile_rest.GitHubGist + sample = '.. gist:: fake_id\n :file: spam.py' + sample_without_filename = '.. gist:: fake_id2' + + def setUp(self): + """ Patch GitHubGist for avoiding network dependency """ + self.gist_type.get_raw_gist_with_filename = lambda *_: 'raw_gist_file' + self.gist_type.get_raw_gist = lambda *_: "raw_gist" + _reload(nikola.plugins.compile_rest) + + def test_gist(self): + """ Test the gist directive with filename """ + self.setHtmlFromRst(self.sample) + output = 'https://gist.github.com/fake_id.js?file=spam.py' + self.assertHTMLContains("script", attributes={"src": output}) + self.assertHTMLContains("pre", text="raw_gist_file") + + def test_gist_without_filename(self): + """ Test the gist directive without filename """ + self.setHtmlFromRst(self.sample_without_filename) + output = 'https://gist.github.com/fake_id2.js' + self.assertHTMLContains("script", attributes={"src": output}) + self.assertHTMLContains("pre", text="raw_gist") + + +class GistIntegrationTestCase(ReSTExtensionTestCase): + """ Test requests integration. The gist plugin uses requests to fetch gist + contents and place it in a noscript tag. + + """ + sample = '.. gist:: 1812835' + + def test_gist_integration(self): + """ Fetch contents of the gist from GH and render in a noscript tag """ + text = ('Be alone, that is the secret of invention: be alone, that is' + ' when ideas are born. -- Nikola Tesla') + self.assertHTMLContains('pre', text=text) + + +class SlidesTestCase(ReSTExtensionTestCase): + """ Slides test case """ + + sample = '.. slides:: IMG.jpg\n' + + def test_slides(self): + """ Test the slides js generation and img tag creation """ + self.assertHTMLContains("img", attributes={"src": "IMG.jpg"}) + + +class SoundCloudTestCase(ReSTExtensionTestCase): + """ SoundCloud test case """ + + sample = '.. soundcloud:: SID\n :height: 400\n :width: 600' + + def test_soundcloud(self): + """ Test SoundCloud iframe tag generation """ + self.assertHTMLContains("iframe", + attributes={"src": ("https://w.soundcloud.com" + "/player/?url=http://" + "api.soundcloud.com/" + "tracks/SID"), + "height": "400", "width": "600"}) + + +class VimeoTestCase(ReSTExtensionTestCase): + """Vimeo test. + Set Vimeo.request_size to False for avoiding querying the Vimeo api + over the network + + """ + sample = '.. vimeo:: VID\n :height: 400\n :width: 600' + + def setUp(self): + """ Disable query of the vimeo api over the wire """ + nikola.plugins.compile_rest.Vimeo.request_size = False + super(VimeoTestCase, self).setUp() + _reload(nikola.plugins.compile_rest) + + def test_vimeo(self): + """ Test Vimeo iframe tag generation """ + self.assertHTMLContains("iframe", + attributes={"src": ("http://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.assertHTMLContains("iframe", + attributes={"src": ("http://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 """ + + sample = '.. listing:: nikola.py python' + sample2 = '.. code-block:: python\n\n import antigravity' + sample3 = '.. sourcecode:: python\n\n import antigravity' + + opener_mock = mock.mock_open(read_data="import antigravity\n") + opener_mock.return_value.readlines.return_value = "import antigravity\n" + + def setUp(self): + """ Inject a mock open function for not generating a test site """ + self.f = StringIO("import antigravity\n") + #_reload(nikola.plugins.compile_rest) + + def test_listing(self): + """ Test that we can render a file object contents without errors """ + with mock.patch("nikola.plugins.compile_rest.listing.codecs_open", self.opener_mock, create=True): + self.setHtmlFromRst(self.sample) + + def test_codeblock_alias(self): + """ Test CodeBlock aliases """ + with mock.patch("nikola.plugins.compile_rest.listing.codecs_open", self.opener_mock, create=True): + self.setHtmlFromRst(self.sample2) + self.setHtmlFromRst(self.sample3) + + +if __name__ == "__main__": + unittest.main() |
