diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/base.py | 24 | ||||
| -rw-r--r-- | tests/data/1-nolinks.rst | 28 | ||||
| -rw-r--r-- | tests/test_command_import_wordpress.py | 67 | ||||
| -rw-r--r-- | tests/test_integration.py | 6 | ||||
| -rw-r--r-- | tests/test_rss_feeds.py | 6 | ||||
| -rw-r--r-- | tests/test_slugify.py | 65 | ||||
| -rw-r--r-- | tests/test_utils.py | 70 |
7 files changed, 203 insertions, 63 deletions
diff --git a/tests/base.py b/tests/base.py index f0bd484..14af18a 100644 --- a/tests/base.py +++ b/tests/base.py @@ -30,8 +30,9 @@ from nikola.plugin_categories import ( TemplateSystem, PageCompiler, TaskMultiplier, - RestExtension, - MarkdownExtension + CompilerExtension, + MarkdownExtension, + RestExtension ) @@ -213,10 +214,11 @@ class FakeSite(object): "TemplateSystem": TemplateSystem, "PageCompiler": PageCompiler, "TaskMultiplier": TaskMultiplier, - "RestExtension": RestExtension, + "CompilerExtension": CompilerExtension, "MarkdownExtension": MarkdownExtension, + "RestExtension": RestExtension }) - self.loghandlers = [nikola.utils.STDERR_HANDLER] + self.loghandlers = nikola.utils.STDERR_HANDLER # TODO remove on v8 self.plugin_manager.setPluginInfoExtension('plugin') if sys.version_info[0] == 3: places = [ @@ -228,6 +230,7 @@ class FakeSite(object): ] self.plugin_manager.setPluginPlaces(places) self.plugin_manager.collectPlugins() + self.compiler_extensions = self._activate_plugins_of_category("CompilerExtension") self.timeline = [ FakePost(title='Fake post', @@ -239,5 +242,18 @@ class FakeSite(object): self.template_system = self self.name = 'mako' + def _activate_plugins_of_category(self, category): + """Activate all the plugins of a given category and return them.""" + # this code duplicated in nikola/nikola.py + plugins = [] + for plugin_info in self.plugin_manager.getPluginsOfCategory(category): + if plugin_info.name in self.config.get('DISABLED_PLUGINS'): + self.plugin_manager.removePluginFromCategory(plugin_info, category) + else: + self.plugin_manager.activatePluginByName(plugin_info.name) + plugin_info.plugin_object.set_site(self) + plugins.append(plugin_info) + return plugins + def render_template(self, name, _, context): return('<img src="IMG.jpg">') diff --git a/tests/data/1-nolinks.rst b/tests/data/1-nolinks.rst new file mode 100644 index 0000000..7f168fb --- /dev/null +++ b/tests/data/1-nolinks.rst @@ -0,0 +1,28 @@ +.. title: Welcome to Nikola +.. slug: welcome-to-nikola +.. date: 2012-03-30 23:00:00 UTC-03:00 +.. tags: nikola, python, demo, blog +.. author: Roberto Alsina +.. link: https://getnikola.com/ +.. description: +.. category: nikola + +.. figure:: http://farm1.staticflickr.com/138/352972944_4f9d568680.jpg + :target: http://farm1.staticflickr.com/138/352972944_4f9d568680_z.jpg?zz=1 + :class: thumbnail + :alt: Nikola Tesla Corner by nicwest, on Flickr + +If you can see this in a web browser, it means you did something wrong, because +you should be reading a nice post with links, and this should be used in +the test suite only. + +Next steps: + +* Read the manual +* Visit the Nikola website to learn more +* See a demo photo gallery +* See a demo listing +* See a demo slideshow +* See a demo of the Bootstrap theme + +Send feedback to info@getnikola.com! diff --git a/tests/test_command_import_wordpress.py b/tests/test_command_import_wordpress.py index 2c47bc3..c1c7836 100644 --- a/tests/test_command_import_wordpress.py +++ b/tests/test_command_import_wordpress.py @@ -2,8 +2,6 @@ from __future__ import unicode_literals, absolute_import import os -import sys - import unittest import mock @@ -172,6 +170,8 @@ class CommandImportWordpressTest(BasicCommandImportWordpress): def test_populate_context(self): channel = self.import_command.get_channel_from_file( self.import_filename) + self.import_command.transform_to_html = False + self.import_command.use_wordpress_compiler = False context = self.import_command.populate_context(channel) for required_key in ('POSTS', 'PAGES', 'COMPILERS'): @@ -188,12 +188,16 @@ class CommandImportWordpressTest(BasicCommandImportWordpress): def test_importing_posts_and_attachments(self): channel = self.import_command.get_channel_from_file( self.import_filename) - self.import_command.context = self.import_command.populate_context( - channel) self.import_command.base_dir = '' self.import_command.output_folder = 'new_site' self.import_command.squash_newlines = True self.import_command.no_downloads = False + self.import_command.export_categories_as_categories = False + self.import_command.export_comments = False + self.import_command.transform_to_html = False + self.import_command.use_wordpress_compiler = False + self.import_command.context = self.import_command.populate_context( + channel) # Ensuring clean results self.import_command.url_map = {} @@ -201,13 +205,15 @@ class CommandImportWordpressTest(BasicCommandImportWordpress): write_metadata = mock.MagicMock() write_content = mock.MagicMock() + write_attachments_info = mock.MagicMock() download_mock = mock.MagicMock() with mock.patch('nikola.plugins.command.import_wordpress.CommandImportWordpress.write_content', write_content): with mock.patch('nikola.plugins.command.import_wordpress.CommandImportWordpress.write_metadata', write_metadata): with mock.patch('nikola.plugins.command.import_wordpress.CommandImportWordpress.download_url_content_to_file', download_mock): - with mock.patch('nikola.plugins.command.import_wordpress.os.makedirs'): - self.import_command.import_posts(channel) + with mock.patch('nikola.plugins.command.import_wordpress.CommandImportWordpress.write_attachments_info', write_attachments_info): + with mock.patch('nikola.plugins.command.import_wordpress.os.makedirs'): + self.import_command.import_posts(channel) self.assertTrue(download_mock.called) qpath = 'new_site/files/wp-content/uploads/2008/07/arzt_und_pfusch-sick-cover.png' @@ -218,10 +224,10 @@ class CommandImportWordpressTest(BasicCommandImportWordpress): self.assertTrue(write_metadata.called) write_metadata.assert_any_call( 'new_site/stories/kontakt.meta'.replace('/', os.sep), 'Kontakt', - 'kontakt', '2009-07-16 20:20:32', '', []) + 'kontakt', '2009-07-16 20:20:32', '', [], **{'wp-status': 'publish'}) self.assertTrue(write_content.called) - write_content.assert_any_call('new_site/posts/2007/04/hoert.wp'.replace('/', os.sep), + write_content.assert_any_call('new_site/posts/2007/04/hoert.md'.replace('/', os.sep), """An image. <img class="size-full wp-image-16" title="caption test" src="http://some.blog/wp-content/uploads/2009/07/caption_test.jpg" alt="caption test" width="739" height="517" /> @@ -238,15 +244,27 @@ print sys.version The end. -""") +""", True) + + self.assertTrue(write_attachments_info.called) + write_attachments_info.assert_any_call('new_site/posts/2008/07/arzt-und-pfusch-s-i-c-k.attachments.json'.replace('/', os.sep), + {10: {'wordpress_user_name': 'Niko', + 'files_meta': [{'width': 300, 'height': 299}, + {'width': b'150', 'size': 'thumbnail', 'height': b'150'}], + 'excerpt': 'Arzt+Pfusch - S.I.C.K.', + 'date_utc': '2009-07-16 19:40:37', + 'content': 'Das Cover von Arzt+Pfusch - S.I.C.K.', + 'files': ['/wp-content/uploads/2008/07/arzt_und_pfusch-sick-cover.png', + '/wp-content/uploads/2008/07/arzt_und_pfusch-sick-cover-150x150.png'], + 'title': 'Arzt+Pfusch - S.I.C.K.'}}) write_content.assert_any_call( - 'new_site/posts/2008/07/arzt-und-pfusch-s-i-c-k.wp'.replace('/', os.sep), + 'new_site/posts/2008/07/arzt-und-pfusch-s-i-c-k.md'.replace('/', os.sep), '''<img class="size-full wp-image-10 alignright" title="Arzt+Pfusch - S.I.C.K." src="http://some.blog/wp-content/uploads/2008/07/arzt_und_pfusch-sick-cover.png" alt="Arzt+Pfusch - S.I.C.K." width="210" height="209" />Arzt+Pfusch - S.I.C.K.Gerade bin ich \xfcber das Album <em>S.I.C.K</em> von <a title="Arzt+Pfusch" href="http://www.arztpfusch.com/" target="_blank">Arzt+Pfusch</a> gestolpert, welches Arzt+Pfusch zum Download f\xfcr lau anbieten. Das Album steht unter einer Creative Commons <a href="http://creativecommons.org/licenses/by-nc-nd/3.0/de/">BY-NC-ND</a>-Lizenz. -Die Ladung <em>noisebmstupidevildustrial</em> gibts als MP3s mit <a href="http://www.archive.org/download/dmp005/dmp005_64kb_mp3.zip">64kbps</a> und <a href="http://www.archive.org/download/dmp005/dmp005_vbr_mp3.zip">VBR</a>, als Ogg Vorbis und als FLAC (letztere <a href="http://www.archive.org/details/dmp005">hier</a>). <a href="http://www.archive.org/download/dmp005/dmp005-artwork.zip">Artwork</a> und <a href="http://www.archive.org/download/dmp005/dmp005-lyrics.txt">Lyrics</a> gibts nochmal einzeln zum Download.''') +Die Ladung <em>noisebmstupidevildustrial</em> gibts als MP3s mit <a href="http://www.archive.org/download/dmp005/dmp005_64kb_mp3.zip">64kbps</a> und <a href="http://www.archive.org/download/dmp005/dmp005_vbr_mp3.zip">VBR</a>, als Ogg Vorbis und als FLAC (letztere <a href="http://www.archive.org/details/dmp005">hier</a>). <a href="http://www.archive.org/download/dmp005/dmp005-artwork.zip">Artwork</a> und <a href="http://www.archive.org/download/dmp005/dmp005-lyrics.txt">Lyrics</a> gibts nochmal einzeln zum Download.''', True) write_content.assert_any_call( - 'new_site/stories/kontakt.wp'.replace('/', os.sep), """<h1>Datenschutz</h1> + 'new_site/stories/kontakt.md'.replace('/', os.sep), """<h1>Datenschutz</h1> Ich erhebe und speichere automatisch in meine Server Log Files Informationen, die dein Browser an mich \xfcbermittelt. Dies sind: @@ -264,7 +282,7 @@ Ich erhebe und speichere automatisch in meine Server Log Files Informationen, di </ul> -Diese Daten sind f\xfcr mich nicht bestimmten Personen zuordenbar. Eine Zusammenf\xfchrung dieser Daten mit anderen Datenquellen wird nicht vorgenommen, die Daten werden einzig zu statistischen Zwecken erhoben.""") +Diese Daten sind f\xfcr mich nicht bestimmten Personen zuordenbar. Eine Zusammenf\xfchrung dieser Daten mit anderen Datenquellen wird nicht vorgenommen, die Daten werden einzig zu statistischen Zwecken erhoben.""", True) self.assertTrue(len(self.import_command.url_map) > 0) @@ -306,10 +324,13 @@ Diese Daten sind f\xfcr mich nicht bestimmten Personen zuordenbar. Eine Zusammen transform_caption = mock.MagicMock() transform_newlines = mock.MagicMock() + self.import_command.transform_to_html = False + self.import_command.use_wordpress_compiler = False + with mock.patch('nikola.plugins.command.import_wordpress.CommandImportWordpress.transform_code', transform_code): with mock.patch('nikola.plugins.command.import_wordpress.CommandImportWordpress.transform_caption', transform_caption): with mock.patch('nikola.plugins.command.import_wordpress.CommandImportWordpress.transform_multiple_newlines', transform_newlines): - self.import_command.transform_content("random content") + self.import_command.transform_content("random content", "wp", None) self.assertTrue(transform_code.called) self.assertTrue(transform_caption.called) @@ -418,21 +439,17 @@ newlines. self.assertTrue(self.import_command.name in config_path_with_timestamp) def test_write_content_does_not_detroy_text(self): - content = b"""<h1>Installation</h1> -Follow the instructions <a title="Installing Jenkins" href="https://wiki.jenkins-ci.org/display/JENKINS/Installing+Jenkins">described here</a>. - -<h1>Plugins</h1> -There are many plugins. -<h2>Violations</h2> -You can use the <a title="Jenkins Plugin: Violations" href="https://wiki.jenkins-ci.org/display/JENKINS/Violations">Violations</a> plugin.""" + content = b"""FOO""" open_mock = mock.mock_open() with mock.patch('nikola.plugins.basic_import.open', open_mock, create=True): self.import_command.write_content('some_file', content) - open_mock.assert_called_once_with('some_file', 'wb+') - call_context = open_mock() - call_context.write.assert_called_once_with( - content.join([b'<html><body>', b'</body></html>'])) + open_mock.assert_has_calls([ + mock.call(u'some_file', u'wb+'), + mock.call().__enter__(), + mock.call().write(b'<html><body><p>FOO</p></body></html>'), + mock.call().__exit__(None, None, None)] + ) def test_configure_redirections(self): """ diff --git a/tests/test_integration.py b/tests/test_integration.py index 62ccd79..4bfd1d2 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -105,6 +105,9 @@ 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) + src1 = os.path.join(os.path.dirname(__file__), 'data', '1-nolinks.rst') + dst1 = os.path.join(self.target_dir, 'posts', '1.rst') + shutil.copy(src1, dst1) # File for Issue #374 (empty post text) with io.open(os.path.join(self.target_dir, 'posts', 'empty.txt'), "w+", encoding="utf8") as outf: outf.write( @@ -526,6 +529,9 @@ class InvariantBuildTest(EmptyBuildTest): """Fill the site with demo content.""" self.init_command.copy_sample_site(self.target_dir) self.init_command.create_configuration(self.target_dir) + src1 = os.path.join(os.path.dirname(__file__), 'data', '1-nolinks.rst') + dst1 = os.path.join(self.target_dir, 'posts', '1.rst') + shutil.copy(src1, dst1) os.system('rm "{0}/stories/creating-a-theme.rst" "{0}/stories/extending.txt" "{0}/stories/internals.txt" "{0}/stories/manual.rst" "{0}/stories/social_buttons.txt" "{0}/stories/theming.rst" "{0}/stories/upgrading-to-v6.txt"'.format(self.target_dir)) def test_invariance(self): diff --git a/tests/test_rss_feeds.py b/tests/test_rss_feeds.py index 992b1b7..f67ed40 100644 --- a/tests/test_rss_feeds.py +++ b/tests/test_rss_feeds.py @@ -91,9 +91,9 @@ class RSSFeedTest(unittest.TestCase): # lxml will complain if the encoding is specified in the # xml when running with unicode strings. # We do not include this in our content. - open_handle = opener_mock() - file_content = [call[1][0] - for call in open_handle.mock_calls[1:-1]][0] + file_content = [ + call[1][0] + for call in opener_mock.mock_calls[2:-1]][0] splitted_content = file_content.split('\n') self.encoding_declaration = splitted_content[0] content_without_encoding_declaration = splitted_content[1:] diff --git a/tests/test_slugify.py b/tests/test_slugify.py new file mode 100644 index 0000000..9dec5a6 --- /dev/null +++ b/tests/test_slugify.py @@ -0,0 +1,65 @@ +# -*- coding: utf-8 -*- + +u"""Test slugify.""" + +from __future__ import unicode_literals +import nikola.utils + + +def test_ascii(): + """Test an ASCII-only string.""" + o = nikola.utils.slugify(u'hello') + assert o == u'hello' + assert isinstance(o, nikola.utils.unicode_str) + + +def test_ascii_dash(): + """Test an ASCII string, with dashes.""" + o = nikola.utils.slugify(u'hello-world') + assert o == u'hello-world' + assert isinstance(o, nikola.utils.unicode_str) + + +def test_ascii_fancy(): + """Test an ASCII string, with fancy characters.""" + o = nikola.utils.slugify(u'The quick brown fox jumps over the lazy dog!-123.456') + assert o == u'the-quick-brown-fox-jumps-over-the-lazy-dog-123456' + assert isinstance(o, nikola.utils.unicode_str) + + +def test_pl(): + """Test a string with Polish diacritical characters.""" + o = nikola.utils.slugify(u'zażółćgęśląjaźń') + assert o == u'zazolcgeslajazn' + assert isinstance(o, nikola.utils.unicode_str) + + +def test_pl_dash(): + """Test a string with Polish diacritical characters and dashes.""" + o = nikola.utils.slugify(u'zażółć-gęślą-jaźń') + assert o == u'zazolc-gesla-jazn' + + +def test_pl_fancy(): + """Test a string with Polish diacritical characters and fancy characters.""" + o = nikola.utils.slugify(u'Zażółć gęślą jaźń!-123.456') + assert o == u'zazolc-gesla-jazn-123456' + assert isinstance(o, nikola.utils.unicode_str) + + +def test_disarmed(): + """Test disarmed slugify.""" + nikola.utils.USE_SLUGIFY = False + o = nikola.utils.slugify(u'Zażółć gęślą jaźń!-123.456') + assert o == u'Zażółć gęślą jaźń!-123.456' + assert isinstance(o, nikola.utils.unicode_str) + nikola.utils.USE_SLUGIFY = True + + +def test_disarmed_weird(): + """Test disarmed slugify with banned characters.""" + nikola.utils.USE_SLUGIFY = False + o = nikola.utils.slugify(u'Zażółć gęślą jaźń!-123.456 "Hello World"?#H<e>l/l\\o:W\'o\rr*l\td|!\n') + assert o == u'Zażółć gęślą jaźń!-123.456 -Hello World---H-e-l-l-o-W-o-r-l-d-!-' + assert isinstance(o, nikola.utils.unicode_str) + nikola.utils.USE_SLUGIFY = True diff --git a/tests/test_utils.py b/tests/test_utils.py index 1e2d3b3..9507de2 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -18,16 +18,15 @@ class dummy(object): class GetMetaTest(unittest.TestCase): def test_getting_metadata_from_content(self): - file_metadata = [".. title: Nikola needs more tests!\n", - ".. slug: write-tests-now\n", - ".. date: 2012/09/15 19:52:05\n", - ".. tags:\n", - ".. link:\n", - ".. description:\n", - "Post content\n"] + file_metadata = ".. title: Nikola needs more tests!\n"\ + ".. slug: write-tests-now\n"\ + ".. date: 2012/09/15 19:52:05\n"\ + ".. tags:\n"\ + ".. link:\n"\ + ".. description:\n"\ + "Post content\n" opener_mock = mock.mock_open(read_data=file_metadata) - opener_mock.return_value.readlines.return_value = file_metadata post = dummy() post.source_path = 'file_with_metadata' @@ -45,16 +44,15 @@ class GetMetaTest(unittest.TestCase): self.assertTrue(nsm) def test_get_title_from_rest(self): - file_metadata = [".. slug: write-tests-now\n", - ".. date: 2012/09/15 19:52:05\n", - ".. tags:\n", - ".. link:\n", - ".. description:\n", - "Post Title\n", - "----------\n"] + file_metadata = ".. slug: write-tests-now\n"\ + ".. date: 2012/09/15 19:52:05\n"\ + ".. tags:\n"\ + ".. link:\n"\ + ".. description:\n\n"\ + "Post Title\n"\ + "----------\n" opener_mock = mock.mock_open(read_data=file_metadata) - opener_mock.return_value.readlines.return_value = file_metadata post = dummy() post.source_path = 'file_with_metadata' @@ -72,14 +70,13 @@ class GetMetaTest(unittest.TestCase): self.assertTrue(nsm) def test_get_title_from_fname(self): - file_metadata = [".. slug: write-tests-now\n", - ".. date: 2012/09/15 19:52:05\n", - ".. tags:\n", - ".. link:\n", - ".. description:\n"] + file_metadata = ".. slug: write-tests-now\n"\ + ".. date: 2012/09/15 19:52:05\n"\ + ".. tags:\n"\ + ".. link:\n"\ + ".. description:\n" opener_mock = mock.mock_open(read_data=file_metadata) - opener_mock.return_value.readlines.return_value = file_metadata post = dummy() post.source_path = 'file_with_metadata' @@ -97,15 +94,14 @@ class GetMetaTest(unittest.TestCase): self.assertTrue(nsm) def test_use_filename_as_slug_fallback(self): - file_metadata = [".. title: Nikola needs more tests!\n", - ".. date: 2012/09/15 19:52:05\n", - ".. tags:\n", - ".. link:\n", - ".. description:\n", - "Post content\n"] + file_metadata = ".. title: Nikola needs more tests!\n"\ + ".. date: 2012/09/15 19:52:05\n"\ + ".. tags:\n"\ + ".. link:\n"\ + ".. description:\n\n"\ + "Post content\n" opener_mock = mock.mock_open(read_data=file_metadata) - opener_mock.return_value.readlines.return_value = file_metadata post = dummy() post.source_path = 'Slugify this' @@ -113,7 +109,6 @@ class GetMetaTest(unittest.TestCase): with mock.patch('nikola.post.io.open', opener_mock, create=True): meta, nsm = get_meta(post, 'Slugify this') - self.assertEqual('Nikola needs more tests!', meta['title']) self.assertEqual('slugify-this', meta['slug']) self.assertEqual('2012/09/15 19:52:05', meta['date']) @@ -250,7 +245,7 @@ class TranslatableSettingsTest(unittest.TestCase): except NameError: # Python 3 u = str(S) - cn = S() # no language specified + cn = S() # no language specified cr = S('xx') # real language specified cf = S('zz') # fake language specified @@ -323,5 +318,18 @@ class TranslatableSettingsTest(unittest.TestCase): self.assertEqual(inp['zz'], cn) +def test_get_metadata_from_file(): + # These were doctests and not running :-P + from nikola.post import _get_metadata_from_file + g = _get_metadata_from_file + assert list(g([]).values()) == [] + assert str(g(["======","FooBar","======"])["title"]) == 'FooBar' + assert str(g(["FooBar","======"])["title"]) == 'FooBar' + assert str(g(["#FooBar"])["title"]) == 'FooBar' + assert str(g([".. title: FooBar"])["title"]) == 'FooBar' + assert 'title' not in g(["","",".. title: FooBar"]) + assert 'title' in g(["",".. title: FooBar"]) + assert 'title' in g([".. foo: bar","","FooBar", "------"]) + if __name__ == '__main__': unittest.main() |
