From ca94afc07df55cb7fc6fe3b4f3011877b7881195 Mon Sep 17 00:00:00 2001 From: Agustin Henze Date: Wed, 20 Nov 2013 16:58:50 -0300 Subject: Imported Upstream version 6.2.1 --- tests/README.rst | 92 +++++++ tests/__init__.py | 0 tests/base.py | 109 +++++++- tests/data/translated_titles/conf.py | 11 +- tests/import_wordpress_and_build_workflow.py | 5 +- tests/test_command_import_wordpress.py | 90 +++++-- tests/test_command_init.py | 12 +- tests/test_compile_markdown.py | 10 +- tests/test_integration.py | 221 ++++++++++++---- tests/test_locale.py | 241 +++++++++++++++++ tests/test_plugin_importing.py | 8 +- tests/test_rss_feeds.py | 28 +- tests/test_rst_compiler.py | 369 +++++++++++++++++++++++++++ tests/test_rst_extensions.py | 223 ---------------- tests/test_scheduling.py | 126 +++++++++ tests/wordpress_export_example.xml | 59 ++++- 16 files changed, 1279 insertions(+), 325 deletions(-) create mode 100644 tests/README.rst create mode 100644 tests/__init__.py create mode 100644 tests/test_locale.py create mode 100644 tests/test_rst_compiler.py delete mode 100644 tests/test_rst_extensions.py create mode 100644 tests/test_scheduling.py (limited to 'tests') diff --git a/tests/README.rst b/tests/README.rst new file mode 100644 index 0000000..2b3afb8 --- /dev/null +++ b/tests/README.rst @@ -0,0 +1,92 @@ +.. title: The Nikola Test Suite +.. slug: tests +.. date: 2012/03/30 23:00 + +The Nikola Test Suite +===================== + +Nikola, like many software projects, has a test suite. There are over 100 +tests. + +Tests (in alphabetical order) +----------------------------- + +* ``test_command_import_wordpress`` tests the WordPress importer for + Nikola. +* ``test_command_init`` checks whether new sites are created properly via the + ``init`` command. +* ``test_compile_markdown`` exercises the Markdown compiler plugin of Nikola. +* ``test_integration`` are used to validate that sites actually build. +* ``test_locale`` tests the locale support of Nikola. +* ``test_plugin_importing`` checks three basic plugins to know whether they + get imported properly. +* ``test_rss_feeds`` asserts that RSS created by Nikola is sane. +* ``test_rst_compiler`` exercises the reStructuredText compiler plugin of + Nikola. +* ``test_scheduling`` performs tests on post scheduling rules. +* ``test_utils`` test various Nikola utilities. + +Requirements to run the tests +----------------------------- + +You need: + +* ``pip install -r requirements-tests.txt`` +* a few minutes’ time +* appropriate locale settings + +How to set the locale for Nikola tests? +--------------------------------------- + +For testing nikola needs to specify two languages, each one with a supported locale. By default, the test suite uses ``en`` and ``es`` as languages, and their respective default locale for them. + +You can set the language - locale pairs by exporting two shell variables, like in:: + + export NIKOLA_LOCALE_DEFAULT=en,en_US.utf8 + export NIKOLA_LOCALE_OTHER=es,es_ES.utf8 + +In Windows that would be:: + + set NIKOLA_LOCALE_DEFAULT=en,English + set NIKOLA_LOCALE_OTHER=es,Spanish + +Replace the part before the comma with a Nikola translation selector (see ``nikola/conf.py.in`` for details), and the part after the comma with an *installed* glibc locale. + +To check if the desired locale is supported in your host you can, in a python console:: + + import locale + locale.setlocale(locale.LC_ALL, 'locale_name') + # by example, 'en_US.utf8' (posix) 'English' (windows) + # if it does not traceback, then python can use that locale + +Alternatively, if you have some disk space to spare, you can install +the two default locales. Here is how to do that in Ubuntu:: + + sudo apt-get install language-pack-en language-pack-es + + +How to execute the tests +------------------------ + +The command to execute tests is:: + + nosetests --with-coverage --cover-package=nikola --with-doctest --doctest-options=+NORMALIZE_WHITESPACE --logging-filter=-yapsy + +However, this command may change at any given moment. Check the +``/.travis.yml`` file to get the current command. + +In Windows you want to drop the doctests parts, they fail over trivial differences in OS details. + +It is also recommended to run ``nikola help`` to see if Nikola actually +works. + +If you are committing code, make sure to run ``flake8 --ignore=E501 .`` to see if you comply with the PEP 8 style guide and do not have basic code mistakes (we ignore the 79-characters-per-line rule). + +In windows ignore the two flake8 diagnostics about messages_sl_si.py , they are artifacts of (symlinks + git + windows). + + +Travis CI +--------- + +We also run our tests on `Travis CI `_. +You can check the `current build status `_ there. diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/base.py b/tests/base.py index 92576c7..00f7486 100644 --- a/tests/base.py +++ b/tests/base.py @@ -6,12 +6,21 @@ """ Base class for Nikola test cases """ -__all__ = ["BaseTestCase"] - +__all__ = ["BaseTestCase", "cd", "LocaleSupportInTesting"] +from contextlib import contextmanager +import locale +import os import sys import unittest +import logbook + +# Make logbook shutup +import nikola.utils + +nikola.utils.LOGGER.handlers.append(logbook.TestHandler()) + if sys.version_info < (2, 7): @@ -56,3 +65,99 @@ if sys.version_info < (2, 7): else: BaseTestCase = unittest.TestCase + + +@contextmanager +def cd(path): + old_dir = os.getcwd() + os.chdir(path) + yield + os.chdir(old_dir) + + +class LocaleSupportInTesting(object): + """ + Nikola needs two pairs of valid (language, locale_n) to test multilingual sites. + + As languages of interest and installed OS support varies from host to host + we allow to specify two such pairs. + + A valid pair complies + 'languaje' one of the names of nikola translations ('en', 'es', ...) + 'locale_n' is a string that python accepts to set a locale, like in + import locale + locale.setlocale(locale.LC_ALL, str(locale_n)) + + You specify the custom pairs to use with two environment variables + NIKOLA_LOCALE_DEFAULT (lang and locale to use as nikola's DEFAULT_LANG) + NIKOLA_LOCALE_OTHER + + The value of the pair is lang (as in keys of Nikola's TRANSLATIONS), followed + by coma, followed by the locale. + """ + + @classmethod + def initialize(cls): + """Determines and diagnoses the two (lang, locale) pairs to use in testing + + While it only needs to run once at the beginning of the testing session, + calling multiple times is fine. + """ + if hasattr(cls, 'langlocales'): + return + defaults = { + 'linux': { + # non-windows defaults, must be two locales suported by .travis.yml + 'default': ("en", str("en_US.utf8")), + 'other': ("es", str("es_ES.utf8")), + }, + 'windows': { + # windows defaults + 'default': ("en", str("English")), + 'other': ("es", str("Spanish")), + }, + } + os_id = 'windows' if sys.platform == 'win32' else 'linux' + langlocales = {} + for suffix in ['other', 'default']: + try: + envar = 'NIKOLA_LOCALE_' + suffix.upper() + s = os.environ[envar] + parts = s.split(',') + lang = parts[0].strip() + try: + locale_n = str(parts[1].strip()) + locale.setlocale(locale.LC_ALL, locale_n) + except Exception: + msg = ("Environment variable {0} fails to specify a valid ,." + + "Check your syntax, check that python supports that locale in your host.") + nikola.utils.LOGGER.error(msg.format(envar)) + sys.exit(1) + except KeyError: + lang, locale_n = defaults[os_id][suffix] + langlocales[suffix] = (lang, locale_n) + if (langlocales['default'][0] == langlocales['other'][0] or + langlocales['default'][1] == langlocales['other'][1]): # NOQA + # the mix of defaults and enviro is not good + msg = ('Locales for testing should differ in lang and locale, else ' + + 'the test would we weak. Check your environment settings for ' + + 'NIKOLA_LOCALE_DEFAULT and NIKOLA_LOCALE_OTHER') + nikola.utils.LOGGER.error(msg) + setattr(cls, 'langlocales', langlocales) + + @classmethod + def initialize_locales_for_testing(cls, variant): + """initializes nikola.utils.LocaleBorg""" + if not hasattr(cls, 'langlocales'): + cls.initialize() + default_lang = cls.langlocales['default'][0] + locales = {} + locales[default_lang] = cls.langlocales['default'][1] + if variant == 'unilingual': + pass + elif variant == 'bilingual': + locales[cls.langlocales['other'][0]] = cls.langlocales['other'][1] + else: + raise ValueError('Unknown locale variant') + nikola.utils.LocaleBorg.reset() + nikola.utils.LocaleBorg.initialize(locales, default_lang) diff --git a/tests/data/translated_titles/conf.py b/tests/data/translated_titles/conf.py index 69c7bc7..b445ba9 100644 --- a/tests/data/translated_titles/conf.py +++ b/tests/data/translated_titles/conf.py @@ -1,4 +1,3 @@ - # -*- coding: utf-8 -*- from __future__ import unicode_literals import time @@ -72,7 +71,7 @@ SIDEBAR_LINKS = { # The wildcard is used to generate a list of reSt source files # (whatever/thing.txt). # That fragment must have an associated metadata file (whatever/thing.meta), -# and opcionally translated files (example for spanish, with code "es"): +# and optionally translated files (example for spanish, with code "es"): # whatever/thing.txt.es and whatever/thing.meta.es # # From those files, a set of HTML fragment files will be generated: @@ -106,7 +105,7 @@ post_pages = ( # 'rest' is reStructuredText # 'markdown' is MarkDown # 'html' assumes the file is html and just copies it -post_compilers = { +COMPILERS = { "rest": ('.txt', '.rst'), "markdown": ('.md', '.mdown', '.markdown'), "textile": ('.textile',), @@ -340,10 +339,14 @@ CONTENT_FOOTER = CONTENT_FOOTER.format(email=BLOG_EMAIL, # external resources. # USE_CDN = False -# Google analytics or whatever else you use. Added to the bottom of +# Google analytics script or whatever else you use. Added to the bottom of # in the default template (base.tmpl). # ANALYTICS = "" +# HTML snippet that will be added at the bottom of body of +# in the default template (base.tmpl). +# SOCIAL_BUTTONS_CODE = "" + # The possibility to extract metadata from the filename by using a # regular expression. # To make it work you need to name parts of your regular expression. diff --git a/tests/import_wordpress_and_build_workflow.py b/tests/import_wordpress_and_build_workflow.py index 90cb6a8..bc04a1f 100644 --- a/tests/import_wordpress_and_build_workflow.py +++ b/tests/import_wordpress_and_build_workflow.py @@ -26,12 +26,13 @@ def main(import_directory=None): test_directory = os.path.dirname(__file__) package_directory = os.path.abspath(os.path.join(test_directory, '..')) - os.system('echo "y" | pip uninstall Nikola') + os.system('pip uninstall -y Nikola') os.system('pip install %s' % package_directory) os.system('nikola') import_file = os.path.join(test_directory, 'wordpress_export_example.xml') os.system( - 'nikola import_wordpress -f %s -o %s' % (import_file, import_directory)) + 'nikola import_wordpress -o {folder} {file}'.format(file=import_file, + folder=import_directory)) assert os.path.exists( import_directory), "The directory %s should be existing." diff --git a/tests/test_command_import_wordpress.py b/tests/test_command_import_wordpress.py index 3be2ad9..f215705 100644 --- a/tests/test_command_import_wordpress.py +++ b/tests/test_command_import_wordpress.py @@ -1,15 +1,19 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals +from __future__ import unicode_literals, absolute_import -from context import nikola +from .context import nikola import os import unittest import mock +import nikola.plugins.command.import_wordpress +from .base import BaseTestCase -class BasicCommandImportWordpress(unittest.TestCase): + +class BasicCommandImportWordpress(BaseTestCase): def setUp(self): - self.import_command = nikola.plugins.command_import_wordpress.CommandImportWordpress() + self.module = nikola.plugins.command.import_wordpress + self.import_command = self.module.CommandImportWordpress() self.import_filename = os.path.abspath(os.path.join( os.path.dirname(__file__), 'wordpress_export_example.xml')) @@ -51,11 +55,11 @@ class CommandImportWordpressRunTest(BasicCommandImportWordpress): site_generation_patch = mock.patch('os.system', self.site_generation) data_import_patch = mock.patch( - 'nikola.plugins.command_import_wordpress.CommandImportWordpress.import_posts', self.data_import) + 'nikola.plugins.command.import_wordpress.CommandImportWordpress.import_posts', self.data_import) write_urlmap_patch = mock.patch( - 'nikola.plugins.command_import_wordpress.CommandImportWordpress.write_urlmap_csv', self.write_urlmap) + 'nikola.plugins.command.import_wordpress.CommandImportWordpress.write_urlmap_csv', self.write_urlmap) write_configuration_patch = mock.patch( - 'nikola.plugins.command_import_wordpress.CommandImportWordpress.write_configuration', self.write_configuration) + 'nikola.plugins.command.import_wordpress.CommandImportWordpress.write_configuration', self.write_configuration) self.patches = [site_generation_patch, data_import_patch, write_urlmap_patch, write_configuration_patch] @@ -117,7 +121,7 @@ class CommandImportWordpressTest(BasicCommandImportWordpress): self.import_filename) context = self.import_command.populate_context(channel) - for required_key in ('POST_PAGES', 'POST_COMPILERS'): + for required_key in ('POSTS', 'PAGES', 'COMPILERS'): self.assertTrue(required_key in context) self.assertEqual('de', context['DEFAULT_LANG']) @@ -133,33 +137,37 @@ class CommandImportWordpressTest(BasicCommandImportWordpress): self.import_filename) self.import_command.context = self.import_command.populate_context( channel) - self.import_command.url_map = {} # For testing we use an empty one. self.import_command.output_folder = 'new_site' self.import_command.squash_newlines = True self.import_command.no_downloads = False + # Ensuring clean results + self.import_command.url_map = {} + self.module.links = {} + write_metadata = mock.MagicMock() write_content = 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'): + 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) self.assertTrue(download_mock.called) + qpath = 'new_site/files/wp-content/uploads/2008/07/arzt_und_pfusch-sick-cover.png' download_mock.assert_any_call( 'http://some.blog/wp-content/uploads/2008/07/arzt_und_pfusch-sick-cover.png', - 'new_site/files/wp-content/uploads/2008/07/arzt_und_pfusch-sick-cover.png') + qpath.replace('/', os.sep)) self.assertTrue(write_metadata.called) write_metadata.assert_any_call( - 'new_site/stories/kontakt.meta', 'Kontakt', + 'new_site/stories/kontakt.meta'.replace('/', os.sep), 'Kontakt', 'kontakt', '2009-07-16 20:20:32', None, []) self.assertTrue(write_content.called) - write_content.assert_any_call('new_site/posts/200704hoert.wp', + write_content.assert_any_call('new_site/posts/200704hoert.wp'.replace('/', os.sep), """An image. caption test @@ -179,11 +187,11 @@ The end. """) write_content.assert_any_call( - 'new_site/posts/200807arzt-und-pfusch-s-i-c-k.wp', + 'new_site/posts/200807arzt-und-pfusch-s-i-c-k.wp'.replace('/', os.sep), '''Arzt+Pfusch - S.I.C.K.Arzt+Pfusch - S.I.C.K.Gerade bin ich \xfcber das Album S.I.C.K von Arzt+Pfusch gestolpert, welches Arzt+Pfusch zum Download f\xfcr lau anbieten. Das Album steht unter einer Creative Commons BY-NC-ND-Lizenz. Die Ladung noisebmstupidevildustrial gibts als MP3s mit 64kbps und VBR, als Ogg Vorbis und als FLAC (letztere hier). Artwork und Lyrics gibts nochmal einzeln zum Download.''') write_content.assert_any_call( - 'new_site/stories/kontakt.wp', """

Datenschutz

+ 'new_site/stories/kontakt.wp'.replace('/', os.sep), """

Datenschutz

Ich erhebe und speichere automatisch in meine Server Log Files Informationen, die dein Browser an mich \xfcbermittelt. Dies sind: