mirror of
https://github.com/getpelican/pelican.git
synced 2025-10-15 20:28:56 +02:00
fulfil pep8 standard
This commit is contained in:
parent
44f9cfaaf1
commit
8993c55e6e
31 changed files with 1259 additions and 868 deletions
|
|
@ -1,5 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals, print_function
|
||||
from __future__ import print_function, unicode_literals
|
||||
AUTHOR = 'Alexis Métaireau'
|
||||
SITENAME = "Alexis' log"
|
||||
SITEURL = 'http://blog.notmyidea.org'
|
||||
|
|
@ -31,17 +31,16 @@ DEFAULT_METADATA = {'yeah': 'it is'}
|
|||
# path-specific metadata
|
||||
EXTRA_PATH_METADATA = {
|
||||
'extra/robots.txt': {'path': 'robots.txt'},
|
||||
}
|
||||
}
|
||||
|
||||
# static paths will be copied without parsing their contents
|
||||
STATIC_PATHS = [
|
||||
'pictures',
|
||||
'extra/robots.txt',
|
||||
]
|
||||
]
|
||||
|
||||
FORMATTED_FIELDS = ['summary', 'custom_formatted_field']
|
||||
|
||||
# foobar will not be used, because it's not in caps. All configuration keys
|
||||
# have to be in caps
|
||||
foobar = "barbaz"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,25 +1,26 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals, print_function
|
||||
__all__ = ['get_article', 'unittest', ]
|
||||
from __future__ import print_function, unicode_literals
|
||||
|
||||
import locale
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
from six import StringIO
|
||||
import logging
|
||||
from logging.handlers import BufferingHandler
|
||||
import unittest
|
||||
import locale
|
||||
|
||||
from functools import wraps
|
||||
from contextlib import contextmanager
|
||||
from tempfile import mkdtemp
|
||||
from functools import wraps
|
||||
from logging.handlers import BufferingHandler
|
||||
from shutil import rmtree
|
||||
from tempfile import mkdtemp
|
||||
|
||||
from six import StringIO
|
||||
|
||||
from pelican.contents import Article
|
||||
from pelican.settings import DEFAULT_CONFIG
|
||||
|
||||
__all__ = ['get_article', 'unittest', ]
|
||||
|
||||
|
||||
@contextmanager
|
||||
def temporary_folder():
|
||||
|
|
@ -167,7 +168,7 @@ def get_settings(**kwargs):
|
|||
Set keyword arguments to override specific settings.
|
||||
"""
|
||||
settings = DEFAULT_CONFIG.copy()
|
||||
for key,value in kwargs.items():
|
||||
for key, value in kwargs.items():
|
||||
settings[key] = value
|
||||
return settings
|
||||
|
||||
|
|
@ -179,10 +180,13 @@ class LogCountHandler(BufferingHandler):
|
|||
logging.handlers.BufferingHandler.__init__(self, capacity)
|
||||
|
||||
def count_logs(self, msg=None, level=None):
|
||||
return len([l for l in self.buffer
|
||||
if (msg is None or re.match(msg, l.getMessage()))
|
||||
and (level is None or l.levelno == level)
|
||||
])
|
||||
return len([
|
||||
l
|
||||
for l
|
||||
in self.buffer
|
||||
if (msg is None or re.match(msg, l.getMessage())) and
|
||||
(level is None or l.levelno == level)
|
||||
])
|
||||
|
||||
|
||||
class LoggedTestCase(unittest.TestCase):
|
||||
|
|
|
|||
|
|
@ -1,7 +1,14 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import os
|
||||
from codecs import open
|
||||
|
||||
from shutil import rmtree
|
||||
from tempfile import mkdtemp
|
||||
|
||||
from pelican.generators import ArticlesGenerator, PagesGenerator
|
||||
from pelican.tests.support import get_settings, unittest
|
||||
|
||||
try:
|
||||
from unittest.mock import MagicMock
|
||||
except ImportError:
|
||||
|
|
@ -10,12 +17,6 @@ except ImportError:
|
|||
except ImportError:
|
||||
MagicMock = False
|
||||
|
||||
from shutil import rmtree
|
||||
from tempfile import mkdtemp
|
||||
|
||||
from pelican.generators import ArticlesGenerator, PagesGenerator
|
||||
from pelican.tests.support import unittest, get_settings
|
||||
|
||||
CUR_DIR = os.path.dirname(__file__)
|
||||
CONTENT_DIR = os.path.join(CUR_DIR, 'content')
|
||||
|
||||
|
|
@ -35,7 +36,6 @@ class TestCache(unittest.TestCase):
|
|||
settings['CACHE_PATH'] = self.temp_cache
|
||||
return settings
|
||||
|
||||
|
||||
@unittest.skipUnless(MagicMock, 'Needs Mock module')
|
||||
def test_article_object_caching(self):
|
||||
"""Test Article objects caching at the generator level"""
|
||||
|
|
@ -44,7 +44,6 @@ class TestCache(unittest.TestCase):
|
|||
settings['DEFAULT_DATE'] = (1970, 1, 1)
|
||||
settings['READERS'] = {'asc': None}
|
||||
|
||||
|
||||
generator = ArticlesGenerator(
|
||||
context=settings.copy(), settings=settings,
|
||||
path=CONTENT_DIR, theme=settings['THEME'], output_path=None)
|
||||
|
|
@ -108,7 +107,9 @@ class TestCache(unittest.TestCase):
|
|||
path=CONTENT_DIR, theme=settings['THEME'], output_path=None)
|
||||
generator.readers.read_file = MagicMock()
|
||||
generator.generate_context()
|
||||
self.assertEqual(generator.readers.read_file.call_count, orig_call_count)
|
||||
self.assertEqual(
|
||||
generator.readers.read_file.call_count,
|
||||
orig_call_count)
|
||||
|
||||
@unittest.skipUnless(MagicMock, 'Needs Mock module')
|
||||
def test_page_object_caching(self):
|
||||
|
|
@ -181,5 +182,6 @@ class TestCache(unittest.TestCase):
|
|||
path=CUR_DIR, theme=settings['THEME'], output_path=None)
|
||||
generator.readers.read_file = MagicMock()
|
||||
generator.generate_context()
|
||||
self.assertEqual(generator.readers.read_file.call_count, orig_call_count)
|
||||
|
||||
self.assertEqual(
|
||||
generator.readers.read_file.call_count,
|
||||
orig_call_count)
|
||||
|
|
|
|||
|
|
@ -1,20 +1,21 @@
|
|||
from __future__ import unicode_literals, absolute_import
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
import logging
|
||||
import locale
|
||||
import logging
|
||||
import os.path
|
||||
import six
|
||||
|
||||
from jinja2.utils import generate_lorem_ipsum
|
||||
from posixpath import join as posix_join
|
||||
from sys import platform
|
||||
|
||||
from pelican.contents import (Page, Article, Static, URLWrapper,
|
||||
Author, Category)
|
||||
from jinja2.utils import generate_lorem_ipsum
|
||||
|
||||
import six
|
||||
|
||||
from pelican.contents import Article, Author, Category, Page, Static
|
||||
from pelican.settings import DEFAULT_CONFIG
|
||||
from pelican.signals import content_object_init
|
||||
from pelican.tests.support import LoggedTestCase, mute, unittest, get_settings
|
||||
from pelican.utils import (path_to_url, truncate_html_words, SafeDatetime,
|
||||
posix_join)
|
||||
from pelican.tests.support import LoggedTestCase, get_settings, unittest
|
||||
from pelican.utils import SafeDatetime, path_to_url, truncate_html_words
|
||||
|
||||
|
||||
# generate one paragraph, enclosed with <p>
|
||||
|
|
@ -49,7 +50,7 @@ class TestPage(unittest.TestCase):
|
|||
# them to initialise object's attributes.
|
||||
metadata = {'foo': 'bar', 'foobar': 'baz', 'title': 'foobar', }
|
||||
page = Page(TEST_CONTENT, metadata=metadata,
|
||||
context={'localsiteurl': ''})
|
||||
context={'localsiteurl': ''})
|
||||
for key, value in metadata.items():
|
||||
self.assertTrue(hasattr(page, key))
|
||||
self.assertEqual(value, getattr(page, key))
|
||||
|
|
@ -139,14 +140,9 @@ class TestPage(unittest.TestCase):
|
|||
page = Page(**page_kwargs)
|
||||
|
||||
# page.locale_date is a unicode string in both python2 and python3
|
||||
dt_date = dt.strftime(DEFAULT_CONFIG['DEFAULT_DATE_FORMAT'])
|
||||
# dt_date is a byte string in python2, and a unicode string in python3
|
||||
# Let's make sure it is a unicode string (relies on python 3.3 supporting the u prefix)
|
||||
if type(dt_date) != type(u''):
|
||||
# python2:
|
||||
dt_date = unicode(dt_date, 'utf8')
|
||||
dt_date = dt.strftime(DEFAULT_CONFIG['DEFAULT_DATE_FORMAT'])
|
||||
|
||||
self.assertEqual(page.locale_date, dt_date )
|
||||
self.assertEqual(page.locale_date, dt_date)
|
||||
page_kwargs['settings'] = get_settings()
|
||||
|
||||
# I doubt this can work on all platforms ...
|
||||
|
|
@ -307,10 +303,14 @@ class TestPage(unittest.TestCase):
|
|||
args['settings'] = get_settings()
|
||||
args['source_path'] = 'content'
|
||||
args['context']['filenames'] = {
|
||||
'images/poster.jpg': type(cls_name, (object,), {'url': 'images/poster.jpg'}),
|
||||
'assets/video.mp4': type(cls_name, (object,), {'url': 'assets/video.mp4'}),
|
||||
'images/graph.svg': type(cls_name, (object,), {'url': 'images/graph.svg'}),
|
||||
'reference.rst': type(cls_name, (object,), {'url': 'reference.html'}),
|
||||
'images/poster.jpg': type(
|
||||
cls_name, (object,), {'url': 'images/poster.jpg'}),
|
||||
'assets/video.mp4': type(
|
||||
cls_name, (object,), {'url': 'assets/video.mp4'}),
|
||||
'images/graph.svg': type(
|
||||
cls_name, (object,), {'url': 'images/graph.svg'}),
|
||||
'reference.rst': type(
|
||||
cls_name, (object,), {'url': 'reference.html'}),
|
||||
}
|
||||
|
||||
# video.poster
|
||||
|
|
@ -325,20 +325,25 @@ class TestPage(unittest.TestCase):
|
|||
content,
|
||||
'There is a video with poster '
|
||||
'<video controls poster="http://notmyidea.org/images/poster.jpg">'
|
||||
'<source src="http://notmyidea.org/assets/video.mp4" type="video/mp4">'
|
||||
'<source src="http://notmyidea.org/assets/video.mp4"'
|
||||
' type="video/mp4">'
|
||||
'</video>'
|
||||
)
|
||||
|
||||
# object.data
|
||||
args['content'] = (
|
||||
'There is a svg object '
|
||||
'<object data="{filename}/images/graph.svg" type="image/svg+xml"></object>'
|
||||
'<object data="{filename}/images/graph.svg"'
|
||||
' type="image/svg+xml">'
|
||||
'</object>'
|
||||
)
|
||||
content = Page(**args).get_content('http://notmyidea.org')
|
||||
self.assertEqual(
|
||||
content,
|
||||
'There is a svg object '
|
||||
'<object data="http://notmyidea.org/images/graph.svg" type="image/svg+xml"></object>'
|
||||
'<object data="http://notmyidea.org/images/graph.svg"'
|
||||
' type="image/svg+xml">'
|
||||
'</object>'
|
||||
)
|
||||
|
||||
# blockquote.cite
|
||||
|
|
@ -350,7 +355,9 @@ class TestPage(unittest.TestCase):
|
|||
self.assertEqual(
|
||||
content,
|
||||
'There is a blockquote with cite attribute '
|
||||
'<blockquote cite="http://notmyidea.org/reference.html">blah blah</blockquote>'
|
||||
'<blockquote cite="http://notmyidea.org/reference.html">'
|
||||
'blah blah'
|
||||
'</blockquote>'
|
||||
)
|
||||
|
||||
def test_intrasite_link_markdown_spaces(self):
|
||||
|
|
@ -401,17 +408,19 @@ class TestArticle(TestPage):
|
|||
|
||||
def test_slugify_category_author(self):
|
||||
settings = get_settings()
|
||||
settings['SLUG_SUBSTITUTIONS'] = [ ('C#', 'csharp') ]
|
||||
settings['SLUG_SUBSTITUTIONS'] = [('C#', 'csharp')]
|
||||
settings['ARTICLE_URL'] = '{author}/{category}/{slug}/'
|
||||
settings['ARTICLE_SAVE_AS'] = '{author}/{category}/{slug}/index.html'
|
||||
article_kwargs = self._copy_page_kwargs()
|
||||
article_kwargs['metadata']['author'] = Author("O'Brien", settings)
|
||||
article_kwargs['metadata']['category'] = Category('C# & stuff', settings)
|
||||
article_kwargs['metadata']['category'] = Category(
|
||||
'C# & stuff', settings)
|
||||
article_kwargs['metadata']['title'] = 'fnord'
|
||||
article_kwargs['settings'] = settings
|
||||
article = Article(**article_kwargs)
|
||||
self.assertEqual(article.url, 'obrien/csharp-stuff/fnord/')
|
||||
self.assertEqual(article.save_as, 'obrien/csharp-stuff/fnord/index.html')
|
||||
self.assertEqual(
|
||||
article.save_as, 'obrien/csharp-stuff/fnord/index.html')
|
||||
|
||||
|
||||
class TestStatic(LoggedTestCase):
|
||||
|
|
@ -426,7 +435,8 @@ class TestStatic(LoggedTestCase):
|
|||
self.context = self.settings.copy()
|
||||
|
||||
self.static = Static(content=None, metadata={}, settings=self.settings,
|
||||
source_path=posix_join('dir', 'foo.jpg'), context=self.context)
|
||||
source_path=posix_join('dir', 'foo.jpg'),
|
||||
context=self.context)
|
||||
|
||||
self.context['filenames'] = {self.static.source_path: self.static}
|
||||
|
||||
|
|
@ -436,8 +446,10 @@ class TestStatic(LoggedTestCase):
|
|||
def test_attach_to_same_dir(self):
|
||||
"""attach_to() overrides a static file's save_as and url.
|
||||
"""
|
||||
page = Page(content="fake page",
|
||||
metadata={'title': 'fakepage'}, settings=self.settings,
|
||||
page = Page(
|
||||
content="fake page",
|
||||
metadata={'title': 'fakepage'},
|
||||
settings=self.settings,
|
||||
source_path=os.path.join('dir', 'fakepage.md'))
|
||||
self.static.attach_to(page)
|
||||
|
||||
|
|
@ -449,7 +461,7 @@ class TestStatic(LoggedTestCase):
|
|||
"""attach_to() preserves dirs inside the linking document dir.
|
||||
"""
|
||||
page = Page(content="fake page", metadata={'title': 'fakepage'},
|
||||
settings=self.settings, source_path='fakepage.md')
|
||||
settings=self.settings, source_path='fakepage.md')
|
||||
self.static.attach_to(page)
|
||||
|
||||
expected_save_as = os.path.join('outpages', 'dir', 'foo.jpg')
|
||||
|
|
@ -460,8 +472,8 @@ class TestStatic(LoggedTestCase):
|
|||
"""attach_to() ignores dirs outside the linking document dir.
|
||||
"""
|
||||
page = Page(content="fake page",
|
||||
metadata={'title': 'fakepage'}, settings=self.settings,
|
||||
source_path=os.path.join('dir', 'otherdir', 'fakepage.md'))
|
||||
metadata={'title': 'fakepage'}, settings=self.settings,
|
||||
source_path=os.path.join('dir', 'otherdir', 'fakepage.md'))
|
||||
self.static.attach_to(page)
|
||||
|
||||
expected_save_as = os.path.join('outpages', 'foo.jpg')
|
||||
|
|
@ -472,8 +484,8 @@ class TestStatic(LoggedTestCase):
|
|||
"""attach_to() does nothing when called a second time.
|
||||
"""
|
||||
page = Page(content="fake page",
|
||||
metadata={'title': 'fakepage'}, settings=self.settings,
|
||||
source_path=os.path.join('dir', 'fakepage.md'))
|
||||
metadata={'title': 'fakepage'}, settings=self.settings,
|
||||
source_path=os.path.join('dir', 'fakepage.md'))
|
||||
|
||||
self.static.attach_to(page)
|
||||
|
||||
|
|
@ -481,8 +493,10 @@ class TestStatic(LoggedTestCase):
|
|||
otherdir_settings.update(dict(
|
||||
PAGE_SAVE_AS=os.path.join('otherpages', '{slug}.html'),
|
||||
PAGE_URL='otherpages/{slug}.html'))
|
||||
otherdir_page = Page(content="other page",
|
||||
metadata={'title': 'otherpage'}, settings=otherdir_settings,
|
||||
otherdir_page = Page(
|
||||
content="other page",
|
||||
metadata={'title': 'otherpage'},
|
||||
settings=otherdir_settings,
|
||||
source_path=os.path.join('dir', 'otherpage.md'))
|
||||
|
||||
self.static.attach_to(otherdir_page)
|
||||
|
|
@ -497,8 +511,10 @@ class TestStatic(LoggedTestCase):
|
|||
"""
|
||||
original_save_as = self.static.save_as
|
||||
|
||||
page = Page(content="fake page",
|
||||
metadata={'title': 'fakepage'}, settings=self.settings,
|
||||
page = Page(
|
||||
content="fake page",
|
||||
metadata={'title': 'fakepage'},
|
||||
settings=self.settings,
|
||||
source_path=os.path.join('dir', 'fakepage.md'))
|
||||
self.static.attach_to(page)
|
||||
|
||||
|
|
@ -511,8 +527,10 @@ class TestStatic(LoggedTestCase):
|
|||
"""
|
||||
original_url = self.static.url
|
||||
|
||||
page = Page(content="fake page",
|
||||
metadata={'title': 'fakepage'}, settings=self.settings,
|
||||
page = Page(
|
||||
content="fake page",
|
||||
metadata={'title': 'fakepage'},
|
||||
settings=self.settings,
|
||||
source_path=os.path.join('dir', 'fakepage.md'))
|
||||
self.static.attach_to(page)
|
||||
|
||||
|
|
@ -523,13 +541,15 @@ class TestStatic(LoggedTestCase):
|
|||
"""attach_to() does not override paths that were overridden elsewhere.
|
||||
(For example, by the user with EXTRA_PATH_METADATA)
|
||||
"""
|
||||
customstatic = Static(content=None,
|
||||
customstatic = Static(
|
||||
content=None,
|
||||
metadata=dict(save_as='customfoo.jpg', url='customfoo.jpg'),
|
||||
settings=self.settings,
|
||||
source_path=os.path.join('dir', 'foo.jpg'),
|
||||
context=self.settings.copy())
|
||||
|
||||
page = Page(content="fake page",
|
||||
page = Page(
|
||||
content="fake page",
|
||||
metadata={'title': 'fakepage'}, settings=self.settings,
|
||||
source_path=os.path.join('dir', 'fakepage.md'))
|
||||
|
||||
|
|
@ -542,13 +562,16 @@ class TestStatic(LoggedTestCase):
|
|||
"""{attach} link syntax triggers output path override & url replacement.
|
||||
"""
|
||||
html = '<a href="{attach}../foo.jpg">link</a>'
|
||||
page = Page(content=html,
|
||||
metadata={'title': 'fakepage'}, settings=self.settings,
|
||||
page = Page(
|
||||
content=html,
|
||||
metadata={'title': 'fakepage'},
|
||||
settings=self.settings,
|
||||
source_path=os.path.join('dir', 'otherdir', 'fakepage.md'),
|
||||
context=self.context)
|
||||
content = page.get_content('')
|
||||
|
||||
self.assertNotEqual(content, html,
|
||||
self.assertNotEqual(
|
||||
content, html,
|
||||
"{attach} link syntax did not trigger URL replacement.")
|
||||
|
||||
expected_save_as = os.path.join('outpages', 'foo.jpg')
|
||||
|
|
@ -561,7 +584,8 @@ class TestStatic(LoggedTestCase):
|
|||
html = '<a href="{tag}foo">link</a>'
|
||||
page = Page(
|
||||
content=html,
|
||||
metadata={'title': 'fakepage'}, settings=self.settings,
|
||||
metadata={'title': 'fakepage'},
|
||||
settings=self.settings,
|
||||
source_path=os.path.join('dir', 'otherdir', 'fakepage.md'),
|
||||
context=self.context)
|
||||
content = page.get_content('')
|
||||
|
|
@ -572,8 +596,10 @@ class TestStatic(LoggedTestCase):
|
|||
"{category} link syntax triggers url replacement."
|
||||
|
||||
html = '<a href="{category}foo">link</a>'
|
||||
page = Page(content=html,
|
||||
metadata={'title': 'fakepage'}, settings=self.settings,
|
||||
page = Page(
|
||||
content=html,
|
||||
metadata={'title': 'fakepage'},
|
||||
settings=self.settings,
|
||||
source_path=os.path.join('dir', 'otherdir', 'fakepage.md'),
|
||||
context=self.context)
|
||||
content = page.get_content('')
|
||||
|
|
@ -588,11 +614,11 @@ class TestStatic(LoggedTestCase):
|
|||
metadata={'title': 'fakepage'}, settings=self.settings,
|
||||
source_path=os.path.join('dir', 'otherdir', 'fakepage.md'),
|
||||
context=self.context)
|
||||
content = page.get_content('')
|
||||
content = page.get_content('')
|
||||
|
||||
self.assertEqual(content, html)
|
||||
self.assertLogCountEqual(
|
||||
count=1,
|
||||
msg="Replacement Indicator 'unknown' not recognized, "
|
||||
"skipping replacement",
|
||||
level=logging.WARNING)
|
||||
count=1,
|
||||
msg="Replacement Indicator 'unknown' not recognized, "
|
||||
"skipping replacement",
|
||||
level=logging.WARNING)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,18 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import locale
|
||||
import os
|
||||
|
||||
from codecs import open
|
||||
from shutil import rmtree
|
||||
from tempfile import mkdtemp
|
||||
|
||||
from pelican.generators import (ArticlesGenerator, Generator, PagesGenerator,
|
||||
StaticGenerator, TemplatePagesGenerator)
|
||||
from pelican.tests.support import get_settings, unittest
|
||||
from pelican.writers import Writer
|
||||
|
||||
try:
|
||||
from unittest.mock import MagicMock
|
||||
except ImportError:
|
||||
|
|
@ -10,14 +20,7 @@ except ImportError:
|
|||
from mock import MagicMock
|
||||
except ImportError:
|
||||
MagicMock = False
|
||||
from shutil import rmtree
|
||||
from tempfile import mkdtemp
|
||||
|
||||
from pelican.generators import (Generator, ArticlesGenerator, PagesGenerator,
|
||||
StaticGenerator, TemplatePagesGenerator)
|
||||
from pelican.writers import Writer
|
||||
from pelican.tests.support import unittest, get_settings
|
||||
import locale
|
||||
|
||||
CUR_DIR = os.path.dirname(__file__)
|
||||
CONTENT_DIR = os.path.join(CUR_DIR, 'content')
|
||||
|
|
@ -35,7 +38,6 @@ class TestGenerator(unittest.TestCase):
|
|||
def tearDown(self):
|
||||
locale.setlocale(locale.LC_ALL, self.old_locale)
|
||||
|
||||
|
||||
def test_include_path(self):
|
||||
self.settings['IGNORE_FILES'] = {'ignored1.rst', 'ignored2.rst'}
|
||||
|
||||
|
|
@ -52,7 +54,8 @@ class TestGenerator(unittest.TestCase):
|
|||
"""Test that Generator.get_files() properly excludes directories.
|
||||
"""
|
||||
# We use our own Generator so we can give it our own content path
|
||||
generator = Generator(context=self.settings.copy(),
|
||||
generator = Generator(
|
||||
context=self.settings.copy(),
|
||||
settings=self.settings,
|
||||
path=os.path.join(CUR_DIR, 'nested_content'),
|
||||
theme=self.settings['THEME'], output_path=None)
|
||||
|
|
@ -60,34 +63,42 @@ class TestGenerator(unittest.TestCase):
|
|||
filepaths = generator.get_files(paths=['maindir'])
|
||||
found_files = {os.path.basename(f) for f in filepaths}
|
||||
expected_files = {'maindir.md', 'subdir.md'}
|
||||
self.assertFalse(expected_files - found_files,
|
||||
self.assertFalse(
|
||||
expected_files - found_files,
|
||||
"get_files() failed to find one or more files")
|
||||
|
||||
# Test string as `paths` argument rather than list
|
||||
filepaths = generator.get_files(paths='maindir')
|
||||
found_files = {os.path.basename(f) for f in filepaths}
|
||||
expected_files = {'maindir.md', 'subdir.md'}
|
||||
self.assertFalse(expected_files - found_files,
|
||||
self.assertFalse(
|
||||
expected_files - found_files,
|
||||
"get_files() failed to find one or more files")
|
||||
|
||||
filepaths = generator.get_files(paths=[''], exclude=['maindir'])
|
||||
found_files = {os.path.basename(f) for f in filepaths}
|
||||
self.assertNotIn('maindir.md', found_files,
|
||||
self.assertNotIn(
|
||||
'maindir.md', found_files,
|
||||
"get_files() failed to exclude a top-level directory")
|
||||
self.assertNotIn('subdir.md', found_files,
|
||||
self.assertNotIn(
|
||||
'subdir.md', found_files,
|
||||
"get_files() failed to exclude a subdir of an excluded directory")
|
||||
|
||||
filepaths = generator.get_files(paths=[''],
|
||||
filepaths = generator.get_files(
|
||||
paths=[''],
|
||||
exclude=[os.path.join('maindir', 'subdir')])
|
||||
found_files = {os.path.basename(f) for f in filepaths}
|
||||
self.assertNotIn('subdir.md', found_files,
|
||||
self.assertNotIn(
|
||||
'subdir.md', found_files,
|
||||
"get_files() failed to exclude a subdirectory")
|
||||
|
||||
filepaths = generator.get_files(paths=[''], exclude=['subdir'])
|
||||
found_files = {os.path.basename(f) for f in filepaths}
|
||||
self.assertIn('subdir.md', found_files,
|
||||
self.assertIn(
|
||||
'subdir.md', found_files,
|
||||
"get_files() excluded a subdirectory by name, ignoring its path")
|
||||
|
||||
|
||||
class TestArticlesGenerator(unittest.TestCase):
|
||||
|
||||
@classmethod
|
||||
|
|
@ -96,7 +107,7 @@ class TestArticlesGenerator(unittest.TestCase):
|
|||
settings['DEFAULT_CATEGORY'] = 'Default'
|
||||
settings['DEFAULT_DATE'] = (1970, 1, 1)
|
||||
settings['READERS'] = {'asc': None}
|
||||
settings['CACHE_CONTENT'] = False # cache not needed for this logic tests
|
||||
settings['CACHE_CONTENT'] = False
|
||||
|
||||
cls.generator = ArticlesGenerator(
|
||||
context=settings.copy(), settings=settings,
|
||||
|
|
@ -152,25 +163,30 @@ class TestArticlesGenerator(unittest.TestCase):
|
|||
['Test mkd File', 'published', 'test', 'article'],
|
||||
['This is a super article !', 'published', 'Yeah', 'article'],
|
||||
['This is a super article !', 'published', 'Yeah', 'article'],
|
||||
['Article with Nonconformant HTML meta tags', 'published', 'Default', 'article'],
|
||||
['Article with Nonconformant HTML meta tags', 'published',
|
||||
'Default', 'article'],
|
||||
['This is a super article !', 'published', 'yeah', 'article'],
|
||||
['This is a super article !', 'published', 'yeah', 'article'],
|
||||
['This is a super article !', 'published', 'yeah', 'article'],
|
||||
['This is a super article !', 'published', 'Default', 'article'],
|
||||
['This is an article with category !', 'published', 'yeah',
|
||||
'article'],
|
||||
['This is an article with multiple authors!', 'published', 'Default', 'article'],
|
||||
['This is an article with multiple authors!', 'published', 'Default', 'article'],
|
||||
['This is an article with multiple authors in list format!', 'published', 'Default', 'article'],
|
||||
['This is an article with multiple authors in lastname, firstname format!', 'published', 'Default', 'article'],
|
||||
['This is an article with multiple authors!', 'published',
|
||||
'Default', 'article'],
|
||||
['This is an article with multiple authors!', 'published',
|
||||
'Default', 'article'],
|
||||
['This is an article with multiple authors in list format!',
|
||||
'published', 'Default', 'article'],
|
||||
['This is an article with multiple authors in lastname, '
|
||||
'firstname format!', 'published', 'Default', 'article'],
|
||||
['This is an article without category !', 'published', 'Default',
|
||||
'article'],
|
||||
'article'],
|
||||
['This is an article without category !', 'published',
|
||||
'TestCategory', 'article'],
|
||||
['An Article With Code Block To Test Typogrify Ignore',
|
||||
'published', 'Default', 'article'],
|
||||
['マックOS X 10.8でパイソンとVirtualenvをインストールと設定', 'published',
|
||||
'指導書', 'article'],
|
||||
'published', 'Default', 'article'],
|
||||
['マックOS X 10.8でパイソンとVirtualenvをインストールと設定',
|
||||
'published', '指導書', 'article'],
|
||||
]
|
||||
self.assertEqual(sorted(articles_expected), sorted(self.articles))
|
||||
|
||||
|
|
@ -292,7 +308,7 @@ class TestArticlesGenerator(unittest.TestCase):
|
|||
generator.generate_period_archives(write)
|
||||
dates = [d for d in generator.dates if d.date.year == 1970]
|
||||
self.assertEqual(len(dates), 1)
|
||||
#among other things it must have at least been called with this
|
||||
# among other things it must have at least been called with this
|
||||
settings["period"] = (1970,)
|
||||
write.assert_called_with("posts/1970/index.html",
|
||||
generator.get_template("period_archives"),
|
||||
|
|
@ -300,37 +316,42 @@ class TestArticlesGenerator(unittest.TestCase):
|
|||
blog=True, dates=dates)
|
||||
|
||||
del settings["period"]
|
||||
settings['MONTH_ARCHIVE_SAVE_AS'] = 'posts/{date:%Y}/{date:%b}/index.html'
|
||||
settings['MONTH_ARCHIVE_SAVE_AS'] = \
|
||||
'posts/{date:%Y}/{date:%b}/index.html'
|
||||
generator = ArticlesGenerator(
|
||||
context=settings, settings=settings,
|
||||
path=CONTENT_DIR, theme=settings['THEME'], output_path=None)
|
||||
generator.generate_context()
|
||||
write = MagicMock()
|
||||
generator.generate_period_archives(write)
|
||||
dates = [d for d in generator.dates if d.date.year == 1970
|
||||
and d.date.month == 1]
|
||||
dates = [d for d in generator.dates
|
||||
if d.date.year == 1970 and d.date.month == 1]
|
||||
self.assertEqual(len(dates), 1)
|
||||
settings["period"] = (1970, "January")
|
||||
#among other things it must have at least been called with this
|
||||
# among other things it must have at least been called with this
|
||||
write.assert_called_with("posts/1970/Jan/index.html",
|
||||
generator.get_template("period_archives"),
|
||||
settings,
|
||||
blog=True, dates=dates)
|
||||
|
||||
del settings["period"]
|
||||
settings['DAY_ARCHIVE_SAVE_AS'] = 'posts/{date:%Y}/{date:%b}/{date:%d}/index.html'
|
||||
settings['DAY_ARCHIVE_SAVE_AS'] = \
|
||||
'posts/{date:%Y}/{date:%b}/{date:%d}/index.html'
|
||||
generator = ArticlesGenerator(
|
||||
context=settings, settings=settings,
|
||||
path=CONTENT_DIR, theme=settings['THEME'], output_path=None)
|
||||
generator.generate_context()
|
||||
write = MagicMock()
|
||||
generator.generate_period_archives(write)
|
||||
dates = [d for d in generator.dates if d.date.year == 1970
|
||||
and d.date.month == 1
|
||||
and d.date.day == 1]
|
||||
dates = [
|
||||
d for d in generator.dates if
|
||||
d.date.year == 1970 and
|
||||
d.date.month == 1 and
|
||||
d.date.day == 1
|
||||
]
|
||||
self.assertEqual(len(dates), 1)
|
||||
settings["period"] = (1970, "January", 1)
|
||||
#among other things it must have at least been called with this
|
||||
# among other things it must have at least been called with this
|
||||
write.assert_called_with("posts/1970/Jan/01/index.html",
|
||||
generator.get_template("period_archives"),
|
||||
settings,
|
||||
|
|
@ -347,11 +368,14 @@ class TestArticlesGenerator(unittest.TestCase):
|
|||
def test_generate_authors(self):
|
||||
"""Check authors generation."""
|
||||
authors = [author.name for author, _ in self.generator.authors]
|
||||
authors_expected = sorted(['Alexis Métaireau', 'Author, First', 'Author, Second', 'First Author', 'Second Author'])
|
||||
authors_expected = sorted(
|
||||
['Alexis Métaireau', 'Author, First', 'Author, Second',
|
||||
'First Author', 'Second Author'])
|
||||
self.assertEqual(sorted(authors), authors_expected)
|
||||
# test for slug
|
||||
authors = [author.slug for author, _ in self.generator.authors]
|
||||
authors_expected = ['alexis-metaireau', 'author-first', 'author-second', 'first-author', 'second-author']
|
||||
authors_expected = ['alexis-metaireau', 'author-first',
|
||||
'author-second', 'first-author', 'second-author']
|
||||
self.assertEqual(sorted(authors), sorted(authors_expected))
|
||||
|
||||
def test_standard_metadata_in_default_metadata(self):
|
||||
|
|
@ -391,7 +415,6 @@ class TestArticlesGenerator(unittest.TestCase):
|
|||
settings = get_settings(filenames={})
|
||||
settings['DEFAULT_CATEGORY'] = 'Default'
|
||||
settings['DEFAULT_DATE'] = (1970, 1, 1)
|
||||
settings['CACHE_CONTENT'] = False # cache not needed for this logic tests
|
||||
settings['ARTICLE_ORDER_BY'] = 'title'
|
||||
|
||||
generator = ArticlesGenerator(
|
||||
|
|
@ -420,7 +443,8 @@ class TestArticlesGenerator(unittest.TestCase):
|
|||
'This is a super article !',
|
||||
'This is a super article !',
|
||||
'This is an article with category !',
|
||||
'This is an article with multiple authors in lastname, firstname format!',
|
||||
('This is an article with multiple authors in lastname, '
|
||||
'firstname format!'),
|
||||
'This is an article with multiple authors in list format!',
|
||||
'This is an article with multiple authors!',
|
||||
'This is an article with multiple authors!',
|
||||
|
|
@ -435,7 +459,6 @@ class TestArticlesGenerator(unittest.TestCase):
|
|||
settings = get_settings(filenames={})
|
||||
settings['DEFAULT_CATEGORY'] = 'Default'
|
||||
settings['DEFAULT_DATE'] = (1970, 1, 1)
|
||||
settings['CACHE_CONTENT'] = False # cache not needed for this logic tests
|
||||
settings['ARTICLE_ORDER_BY'] = 'reversed-title'
|
||||
|
||||
generator = ArticlesGenerator(
|
||||
|
|
@ -561,7 +584,7 @@ class TestPageGenerator(unittest.TestCase):
|
|||
are generated correctly on pages
|
||||
"""
|
||||
settings = get_settings(filenames={})
|
||||
settings['PAGE_PATHS'] = ['TestPages'] # relative to CUR_DIR
|
||||
settings['PAGE_PATHS'] = ['TestPages'] # relative to CUR_DIR
|
||||
settings['CACHE_PATH'] = self.temp_cache
|
||||
settings['DEFAULT_DATE'] = (1970, 1, 1)
|
||||
|
||||
|
|
@ -586,7 +609,6 @@ class TestTemplatePagesGenerator(unittest.TestCase):
|
|||
self.old_locale = locale.setlocale(locale.LC_ALL)
|
||||
locale.setlocale(locale.LC_ALL, str('C'))
|
||||
|
||||
|
||||
def tearDown(self):
|
||||
rmtree(self.temp_content)
|
||||
rmtree(self.temp_output)
|
||||
|
|
@ -632,59 +654,67 @@ class TestStaticGenerator(unittest.TestCase):
|
|||
def test_static_excludes(self):
|
||||
"""Test that StaticGenerator respects STATIC_EXCLUDES.
|
||||
"""
|
||||
settings = get_settings(STATIC_EXCLUDES=['subdir'],
|
||||
PATH=self.content_path, STATIC_PATHS=[''])
|
||||
settings = get_settings(
|
||||
STATIC_EXCLUDES=['subdir'],
|
||||
PATH=self.content_path,
|
||||
STATIC_PATHS=[''],
|
||||
filenames={})
|
||||
context = settings.copy()
|
||||
context['filenames'] = {}
|
||||
|
||||
StaticGenerator(context=context, settings=settings,
|
||||
StaticGenerator(
|
||||
context=context, settings=settings,
|
||||
path=settings['PATH'], output_path=None,
|
||||
theme=settings['THEME']).generate_context()
|
||||
|
||||
staticnames = [os.path.basename(c.source_path)
|
||||
for c in context['staticfiles']]
|
||||
for c in context['staticfiles']]
|
||||
|
||||
self.assertNotIn('subdir_fake_image.jpg', staticnames,
|
||||
self.assertNotIn(
|
||||
'subdir_fake_image.jpg', staticnames,
|
||||
"StaticGenerator processed a file in a STATIC_EXCLUDES directory")
|
||||
self.assertIn('fake_image.jpg', staticnames,
|
||||
self.assertIn(
|
||||
'fake_image.jpg', staticnames,
|
||||
"StaticGenerator skipped a file that it should have included")
|
||||
|
||||
def test_static_exclude_sources(self):
|
||||
"""Test that StaticGenerator respects STATIC_EXCLUDE_SOURCES.
|
||||
"""
|
||||
# Test STATIC_EXCLUDE_SOURCES=True
|
||||
|
||||
settings = get_settings(STATIC_EXCLUDE_SOURCES=True,
|
||||
PATH=self.content_path, PAGE_PATHS=[''], STATIC_PATHS=[''],
|
||||
CACHE_CONTENT=False)
|
||||
settings = get_settings(
|
||||
STATIC_EXCLUDE_SOURCES=True,
|
||||
PATH=self.content_path,
|
||||
PAGE_PATHS=[''],
|
||||
STATIC_PATHS=[''],
|
||||
CACHE_CONTENT=False,
|
||||
filenames={})
|
||||
context = settings.copy()
|
||||
context['filenames'] = {}
|
||||
|
||||
for generator_class in (PagesGenerator, StaticGenerator):
|
||||
generator_class(context=context, settings=settings,
|
||||
generator_class(
|
||||
context=context, settings=settings,
|
||||
path=settings['PATH'], output_path=None,
|
||||
theme=settings['THEME']).generate_context()
|
||||
|
||||
staticnames = [os.path.basename(c.source_path)
|
||||
for c in context['staticfiles']]
|
||||
for c in context['staticfiles']]
|
||||
|
||||
self.assertFalse(any(name.endswith(".md") for name in staticnames),
|
||||
self.assertFalse(
|
||||
any(name.endswith(".md") for name in staticnames),
|
||||
"STATIC_EXCLUDE_SOURCES=True failed to exclude a markdown file")
|
||||
|
||||
# Test STATIC_EXCLUDE_SOURCES=False
|
||||
|
||||
settings.update(STATIC_EXCLUDE_SOURCES=False)
|
||||
context = settings.copy()
|
||||
context['filenames'] = {}
|
||||
|
||||
for generator_class in (PagesGenerator, StaticGenerator):
|
||||
generator_class(context=context, settings=settings,
|
||||
generator_class(
|
||||
context=context, settings=settings,
|
||||
path=settings['PATH'], output_path=None,
|
||||
theme=settings['THEME']).generate_context()
|
||||
|
||||
staticnames = [os.path.basename(c.source_path)
|
||||
for c in context['staticfiles']]
|
||||
for c in context['staticfiles']]
|
||||
|
||||
self.assertTrue(any(name.endswith(".md") for name in staticnames),
|
||||
self.assertTrue(
|
||||
any(name.endswith(".md") for name in staticnames),
|
||||
"STATIC_EXCLUDE_SOURCES=False failed to include a markdown file")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,16 +1,19 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals, print_function
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import print_function, unicode_literals
|
||||
|
||||
import locale
|
||||
import os
|
||||
import re
|
||||
|
||||
import locale
|
||||
from codecs import open
|
||||
from pelican.tools.pelican_import import wp2fields, fields2pelican, decode_wp_content, build_header, build_markdown_header, get_attachments, download_attachments
|
||||
from pelican.tests.support import (unittest, temporary_folder, mute,
|
||||
skipIfNoExecutable)
|
||||
|
||||
from pelican.utils import slugify, path_to_file_url
|
||||
from pelican.tests.support import (mute, skipIfNoExecutable, temporary_folder,
|
||||
unittest)
|
||||
from pelican.tools.pelican_import import (build_header, build_markdown_header,
|
||||
decode_wp_content,
|
||||
download_attachments, fields2pelican,
|
||||
get_attachments, wp2fields)
|
||||
from pelican.utils import path_to_file_url, slugify
|
||||
|
||||
CUR_DIR = os.path.abspath(os.path.dirname(__file__))
|
||||
WORDPRESS_XML_SAMPLE = os.path.join(CUR_DIR, 'content', 'wordpressexport.xml')
|
||||
|
|
@ -32,7 +35,6 @@ except ImportError:
|
|||
LXML = False
|
||||
|
||||
|
||||
|
||||
@skipIfNoExecutable(['pandoc', '--version'])
|
||||
@unittest.skipUnless(BeautifulSoup, 'Needs BeautifulSoup module')
|
||||
class TestWordpressXmlImporter(unittest.TestCase):
|
||||
|
|
@ -48,17 +50,19 @@ class TestWordpressXmlImporter(unittest.TestCase):
|
|||
|
||||
def test_ignore_empty_posts(self):
|
||||
self.assertTrue(self.posts)
|
||||
for title, content, fname, date, author, categ, tags, status, kind, format in self.posts:
|
||||
self.assertTrue(title.strip())
|
||||
for (title, content, fname, date, author,
|
||||
categ, tags, status, kind, format) in self.posts:
|
||||
self.assertTrue(title.strip())
|
||||
|
||||
def test_recognise_page_kind(self):
|
||||
""" Check that we recognise pages in wordpress, as opposed to posts """
|
||||
self.assertTrue(self.posts)
|
||||
# Collect (title, filename, kind) of non-empty posts recognised as page
|
||||
pages_data = []
|
||||
for title, content, fname, date, author, categ, tags, status, kind, format in self.posts:
|
||||
if kind == 'page':
|
||||
pages_data.append((title, fname))
|
||||
for (title, content, fname, date, author,
|
||||
categ, tags, status, kind, format) in self.posts:
|
||||
if kind == 'page':
|
||||
pages_data.append((title, fname))
|
||||
self.assertEqual(2, len(pages_data))
|
||||
self.assertEqual(('Page', 'contact'), pages_data[0])
|
||||
self.assertEqual(('Empty Page', 'empty'), pages_data[1])
|
||||
|
|
@ -67,7 +71,8 @@ class TestWordpressXmlImporter(unittest.TestCase):
|
|||
silent_f2p = mute(True)(fields2pelican)
|
||||
test_post = filter(lambda p: p[0].startswith("Empty Page"), self.posts)
|
||||
with temporary_folder() as temp:
|
||||
fname = list(silent_f2p(test_post, 'markdown', temp, dirpage=True))[0]
|
||||
fname = list(silent_f2p(test_post, 'markdown',
|
||||
temp, dirpage=True))[0]
|
||||
self.assertTrue(fname.endswith('pages%sempty.md' % os.path.sep))
|
||||
|
||||
def test_dircat(self):
|
||||
|
|
@ -75,10 +80,11 @@ class TestWordpressXmlImporter(unittest.TestCase):
|
|||
test_posts = []
|
||||
for post in self.posts:
|
||||
# check post kind
|
||||
if len(post[5]) > 0: # Has a category
|
||||
if len(post[5]) > 0: # Has a category
|
||||
test_posts.append(post)
|
||||
with temporary_folder() as temp:
|
||||
fnames = list(silent_f2p(test_posts, 'markdown', temp, dircat=True))
|
||||
fnames = list(silent_f2p(test_posts, 'markdown',
|
||||
temp, dircat=True))
|
||||
index = 0
|
||||
for post in test_posts:
|
||||
name = post[2]
|
||||
|
|
@ -92,25 +98,33 @@ class TestWordpressXmlImporter(unittest.TestCase):
|
|||
def test_unless_custom_post_all_items_should_be_pages_or_posts(self):
|
||||
self.assertTrue(self.posts)
|
||||
pages_data = []
|
||||
for title, content, fname, date, author, categ, tags, status, kind, format in self.posts:
|
||||
if kind == 'page' or kind == 'article':
|
||||
pass
|
||||
else:
|
||||
pages_data.append((title, fname))
|
||||
for (title, content, fname, date, author, categ,
|
||||
tags, status, kind, format) in self.posts:
|
||||
if kind == 'page' or kind == 'article':
|
||||
pass
|
||||
else:
|
||||
pages_data.append((title, fname))
|
||||
self.assertEqual(0, len(pages_data))
|
||||
|
||||
def test_recognise_custom_post_type(self):
|
||||
self.assertTrue(self.custposts)
|
||||
cust_data = []
|
||||
for title, content, fname, date, author, categ, tags, status, kind, format in self.custposts:
|
||||
if kind == 'article' or kind == 'page':
|
||||
pass
|
||||
else:
|
||||
cust_data.append((title, kind))
|
||||
for (title, content, fname, date, author, categ,
|
||||
tags, status, kind, format) in self.custposts:
|
||||
if kind == 'article' or kind == 'page':
|
||||
pass
|
||||
else:
|
||||
cust_data.append((title, kind))
|
||||
self.assertEqual(3, len(cust_data))
|
||||
self.assertEqual(('A custom post in category 4', 'custom1'), cust_data[0])
|
||||
self.assertEqual(('A custom post in category 5', 'custom1'), cust_data[1])
|
||||
self.assertEqual(('A 2nd custom post type also in category 5', 'custom2'), cust_data[2])
|
||||
self.assertEqual(
|
||||
('A custom post in category 4', 'custom1'),
|
||||
cust_data[0])
|
||||
self.assertEqual(
|
||||
('A custom post in category 5', 'custom1'),
|
||||
cust_data[1])
|
||||
self.assertEqual(
|
||||
('A 2nd custom post type also in category 5', 'custom2'),
|
||||
cust_data[2])
|
||||
|
||||
def test_custom_posts_put_in_own_dir(self):
|
||||
silent_f2p = mute(True)(fields2pelican)
|
||||
|
|
@ -122,7 +136,8 @@ class TestWordpressXmlImporter(unittest.TestCase):
|
|||
else:
|
||||
test_posts.append(post)
|
||||
with temporary_folder() as temp:
|
||||
fnames = list(silent_f2p(test_posts, 'markdown', temp, wp_custpost = True))
|
||||
fnames = list(silent_f2p(test_posts, 'markdown',
|
||||
temp, wp_custpost=True))
|
||||
index = 0
|
||||
for post in test_posts:
|
||||
name = post[2]
|
||||
|
|
@ -144,7 +159,7 @@ class TestWordpressXmlImporter(unittest.TestCase):
|
|||
test_posts.append(post)
|
||||
with temporary_folder() as temp:
|
||||
fnames = list(silent_f2p(test_posts, 'markdown', temp,
|
||||
wp_custpost=True, dircat=True))
|
||||
wp_custpost=True, dircat=True))
|
||||
index = 0
|
||||
for post in test_posts:
|
||||
name = post[2]
|
||||
|
|
@ -157,7 +172,7 @@ class TestWordpressXmlImporter(unittest.TestCase):
|
|||
index += 1
|
||||
|
||||
def test_wp_custpost_true_dirpage_false(self):
|
||||
#pages should only be put in their own directory when dirpage = True
|
||||
# pages should only be put in their own directory when dirpage = True
|
||||
silent_f2p = mute(True)(fields2pelican)
|
||||
test_posts = []
|
||||
for post in self.custposts:
|
||||
|
|
@ -166,7 +181,7 @@ class TestWordpressXmlImporter(unittest.TestCase):
|
|||
test_posts.append(post)
|
||||
with temporary_folder() as temp:
|
||||
fnames = list(silent_f2p(test_posts, 'markdown', temp,
|
||||
wp_custpost=True, dirpage=False))
|
||||
wp_custpost=True, dirpage=False))
|
||||
index = 0
|
||||
for post in test_posts:
|
||||
name = post[2]
|
||||
|
|
@ -175,7 +190,6 @@ class TestWordpressXmlImporter(unittest.TestCase):
|
|||
out_name = fnames[index]
|
||||
self.assertFalse(out_name.endswith(filename))
|
||||
|
||||
|
||||
def test_can_toggle_raw_html_code_parsing(self):
|
||||
def r(f):
|
||||
with open(f, encoding='utf-8') as infile:
|
||||
|
|
@ -184,10 +198,12 @@ class TestWordpressXmlImporter(unittest.TestCase):
|
|||
|
||||
with temporary_folder() as temp:
|
||||
|
||||
rst_files = (r(f) for f in silent_f2p(self.posts, 'markdown', temp))
|
||||
rst_files = (r(f) for f
|
||||
in silent_f2p(self.posts, 'markdown', temp))
|
||||
self.assertTrue(any('<iframe' in rst for rst in rst_files))
|
||||
rst_files = (r(f) for f in silent_f2p(self.posts, 'markdown', temp,
|
||||
strip_raw=True))
|
||||
rst_files = (r(f) for f
|
||||
in silent_f2p(self.posts, 'markdown',
|
||||
temp, strip_raw=True))
|
||||
self.assertFalse(any('<iframe' in rst for rst in rst_files))
|
||||
# no effect in rst
|
||||
rst_files = (r(f) for f in silent_f2p(self.posts, 'rst', temp))
|
||||
|
|
@ -197,13 +213,14 @@ class TestWordpressXmlImporter(unittest.TestCase):
|
|||
self.assertFalse(any('<iframe' in rst for rst in rst_files))
|
||||
|
||||
def test_decode_html_entities_in_titles(self):
|
||||
test_posts = [post for post in self.posts if post[2] == 'html-entity-test']
|
||||
test_posts = [post for post
|
||||
in self.posts if post[2] == 'html-entity-test']
|
||||
self.assertEqual(len(test_posts), 1)
|
||||
|
||||
post = test_posts[0]
|
||||
title = post[0]
|
||||
self.assertTrue(title, "A normal post with some <html> entities in the"
|
||||
" title. You can't miss them.")
|
||||
self.assertTrue(title, "A normal post with some <html> entities in "
|
||||
"the title. You can't miss them.")
|
||||
self.assertNotIn('&', title)
|
||||
|
||||
def test_decode_wp_content_returns_empty(self):
|
||||
|
|
@ -216,14 +233,18 @@ class TestWordpressXmlImporter(unittest.TestCase):
|
|||
encoded_content = encoded_file.read()
|
||||
with open(WORDPRESS_DECODED_CONTENT_SAMPLE, 'r') as decoded_file:
|
||||
decoded_content = decoded_file.read()
|
||||
self.assertEqual(decode_wp_content(encoded_content, br=False), decoded_content)
|
||||
self.assertEqual(
|
||||
decode_wp_content(encoded_content, br=False),
|
||||
decoded_content)
|
||||
|
||||
def test_preserve_verbatim_formatting(self):
|
||||
def r(f):
|
||||
with open(f, encoding='utf-8') as infile:
|
||||
return infile.read()
|
||||
silent_f2p = mute(True)(fields2pelican)
|
||||
test_post = filter(lambda p: p[0].startswith("Code in List"), self.posts)
|
||||
test_post = filter(
|
||||
lambda p: p[0].startswith("Code in List"),
|
||||
self.posts)
|
||||
with temporary_folder() as temp:
|
||||
md = [r(f) for f in silent_f2p(test_post, 'markdown', temp)][0]
|
||||
self.assertTrue(re.search(r'\s+a = \[1, 2, 3\]', md))
|
||||
|
|
@ -231,14 +252,17 @@ class TestWordpressXmlImporter(unittest.TestCase):
|
|||
|
||||
for_line = re.search(r'\s+for i in zip\(a, b\):', md).group(0)
|
||||
print_line = re.search(r'\s+print i', md).group(0)
|
||||
self.assertTrue(for_line.rindex('for') < print_line.rindex('print'))
|
||||
self.assertTrue(
|
||||
for_line.rindex('for') < print_line.rindex('print'))
|
||||
|
||||
def test_code_in_list(self):
|
||||
def r(f):
|
||||
with open(f, encoding='utf-8') as infile:
|
||||
return infile.read()
|
||||
silent_f2p = mute(True)(fields2pelican)
|
||||
test_post = filter(lambda p: p[0].startswith("Code in List"), self.posts)
|
||||
test_post = filter(
|
||||
lambda p: p[0].startswith("Code in List"),
|
||||
self.posts)
|
||||
with temporary_folder() as temp:
|
||||
md = [r(f) for f in silent_f2p(test_post, 'markdown', temp)][0]
|
||||
sample_line = re.search(r'- This is a code sample', md).group(0)
|
||||
|
|
@ -285,26 +309,29 @@ class TestBuildHeader(unittest.TestCase):
|
|||
self.assertEqual(build_header(*header_data), expected_docutils)
|
||||
self.assertEqual(build_markdown_header(*header_data), expected_md)
|
||||
|
||||
|
||||
def test_build_header_with_east_asian_characters(self):
|
||||
header = build_header('これは広い幅の文字だけで構成されたタイトルです',
|
||||
None, None, None, None, None)
|
||||
None, None, None, None, None)
|
||||
|
||||
self.assertEqual(header,
|
||||
'これは広い幅の文字だけで構成されたタイトルです\n' +
|
||||
'##############################################\n\n')
|
||||
('これは広い幅の文字だけで構成されたタイトルです\n'
|
||||
'##############################################'
|
||||
'\n\n'))
|
||||
|
||||
def test_galleries_added_to_header(self):
|
||||
header = build_header('test', None, None, None, None,
|
||||
None, attachments=['output/test1', 'output/test2'])
|
||||
self.assertEqual(header, 'test\n####\n' + ':attachments: output/test1, '
|
||||
+ 'output/test2\n\n')
|
||||
header = build_header('test', None, None, None, None, None,
|
||||
attachments=['output/test1', 'output/test2'])
|
||||
self.assertEqual(header, ('test\n####\n'
|
||||
':attachments: output/test1, '
|
||||
'output/test2\n\n'))
|
||||
|
||||
def test_galleries_added_to_markdown_header(self):
|
||||
header = build_markdown_header('test', None, None, None, None, None,
|
||||
attachments=['output/test1', 'output/test2'])
|
||||
self.assertEqual(header, 'Title: test\n' + 'Attachments: output/test1, '
|
||||
+ 'output/test2\n\n')
|
||||
attachments=['output/test1',
|
||||
'output/test2'])
|
||||
self.assertEqual(
|
||||
header,
|
||||
'Title: test\nAttachments: output/test1, output/test2\n\n')
|
||||
|
||||
|
||||
@unittest.skipUnless(BeautifulSoup, 'Needs BeautifulSoup module')
|
||||
|
|
@ -326,14 +353,24 @@ class TestWordpressXMLAttachements(unittest.TestCase):
|
|||
self.assertTrue(self.attachments)
|
||||
for post in self.attachments.keys():
|
||||
if post is None:
|
||||
self.assertTrue(self.attachments[post][0] == 'https://upload.wikimedia.org/wikipedia/commons/thumb/2/2c/Pelican_lakes_entrance02.jpg/240px-Pelican_lakes_entrance02.jpg')
|
||||
expected = ('https://upload.wikimedia.org/wikipedia/commons/'
|
||||
'thumb/2/2c/Pelican_lakes_entrance02.jpg/'
|
||||
'240px-Pelican_lakes_entrance02.jpg')
|
||||
self.assertEqual(self.attachments[post][0], expected)
|
||||
elif post == 'with-excerpt':
|
||||
self.assertTrue(self.attachments[post][0] == 'http://thisurlisinvalid.notarealdomain/not_an_image.jpg')
|
||||
self.assertTrue(self.attachments[post][1] == 'http://en.wikipedia.org/wiki/File:Pelikan_Walvis_Bay.jpg')
|
||||
expected_invalid = ('http://thisurlisinvalid.notarealdomain/'
|
||||
'not_an_image.jpg')
|
||||
expected_pelikan = ('http://en.wikipedia.org/wiki/'
|
||||
'File:Pelikan_Walvis_Bay.jpg')
|
||||
self.assertEqual(self.attachments[post][0], expected_invalid)
|
||||
self.assertEqual(self.attachments[post][1], expected_pelikan)
|
||||
elif post == 'with-tags':
|
||||
self.assertTrue(self.attachments[post][0] == 'http://thisurlisinvalid.notarealdomain')
|
||||
expected_invalid = ('http://thisurlisinvalid.notarealdomain')
|
||||
self.assertEqual(self.attachments[post][0], expected_invalid)
|
||||
else:
|
||||
self.fail('all attachments should match to a filename or None, {}'.format(post))
|
||||
self.fail('all attachments should match to a '
|
||||
'filename or None, {}'
|
||||
.format(post))
|
||||
|
||||
def test_download_attachments(self):
|
||||
real_file = os.path.join(CUR_DIR, 'content/article.rst')
|
||||
|
|
@ -344,4 +381,6 @@ class TestWordpressXMLAttachements(unittest.TestCase):
|
|||
locations = list(silent_da(temp, [good_url, bad_url]))
|
||||
self.assertEqual(1, len(locations))
|
||||
directory = locations[0]
|
||||
self.assertTrue(directory.endswith(os.path.join('content', 'article.rst')), directory)
|
||||
self.assertTrue(
|
||||
directory.endswith(os.path.join('content', 'article.rst')),
|
||||
directory)
|
||||
|
|
|
|||
|
|
@ -1,18 +1,21 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals, absolute_import
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
import locale
|
||||
|
||||
from pelican.tests.support import unittest, get_settings
|
||||
|
||||
from pelican.paginator import Paginator
|
||||
from pelican.contents import Article, Author
|
||||
from pelican.settings import DEFAULT_CONFIG
|
||||
from jinja2.utils import generate_lorem_ipsum
|
||||
|
||||
from pelican.contents import Article, Author
|
||||
from pelican.paginator import Paginator
|
||||
from pelican.settings import DEFAULT_CONFIG
|
||||
from pelican.tests.support import get_settings, unittest
|
||||
|
||||
|
||||
# generate one paragraph, enclosed with <p>
|
||||
TEST_CONTENT = str(generate_lorem_ipsum(n=1))
|
||||
TEST_SUMMARY = generate_lorem_ipsum(n=1, html=False)
|
||||
|
||||
|
||||
class TestPage(unittest.TestCase):
|
||||
def setUp(self):
|
||||
super(TestPage, self).setUp()
|
||||
|
|
@ -49,7 +52,8 @@ class TestPage(unittest.TestCase):
|
|||
)
|
||||
|
||||
self.page_kwargs['metadata']['author'] = Author('Blogger', settings)
|
||||
object_list = [Article(**self.page_kwargs), Article(**self.page_kwargs)]
|
||||
object_list = [Article(**self.page_kwargs),
|
||||
Article(**self.page_kwargs)]
|
||||
paginator = Paginator('foobar.foo', object_list, settings)
|
||||
page = paginator.page(1)
|
||||
self.assertEqual(page.save_as, 'foobar.foo')
|
||||
|
|
|
|||
|
|
@ -1,23 +1,25 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals, print_function
|
||||
from __future__ import print_function, unicode_literals
|
||||
|
||||
import collections
|
||||
import os
|
||||
import sys
|
||||
from tempfile import mkdtemp
|
||||
from shutil import rmtree
|
||||
import locale
|
||||
import logging
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from shutil import rmtree
|
||||
from tempfile import mkdtemp
|
||||
|
||||
from pelican import Pelican
|
||||
from pelican.generators import StaticGenerator
|
||||
from pelican.settings import read_settings
|
||||
from pelican.tests.support import LoggedTestCase, mute, locale_available, unittest
|
||||
from pelican.tests.support import (LoggedTestCase, locale_available,
|
||||
mute, unittest)
|
||||
|
||||
CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
SAMPLES_PATH = os.path.abspath(os.path.join(
|
||||
CURRENT_DIR, os.pardir, os.pardir, 'samples'))
|
||||
CURRENT_DIR, os.pardir, os.pardir, 'samples'))
|
||||
OUTPUT_PATH = os.path.abspath(os.path.join(CURRENT_DIR, 'output'))
|
||||
|
||||
INPUT_PATH = os.path.join(SAMPLES_PATH, "content")
|
||||
|
|
@ -27,13 +29,10 @@ SAMPLE_FR_CONFIG = os.path.join(SAMPLES_PATH, "pelican.conf_FR.py")
|
|||
|
||||
def recursiveDiff(dcmp):
|
||||
diff = {
|
||||
'diff_files': [os.path.join(dcmp.right, f)
|
||||
for f in dcmp.diff_files],
|
||||
'left_only': [os.path.join(dcmp.right, f)
|
||||
for f in dcmp.left_only],
|
||||
'right_only': [os.path.join(dcmp.right, f)
|
||||
for f in dcmp.right_only],
|
||||
}
|
||||
'diff_files': [os.path.join(dcmp.right, f) for f in dcmp.diff_files],
|
||||
'left_only': [os.path.join(dcmp.right, f) for f in dcmp.left_only],
|
||||
'right_only': [os.path.join(dcmp.right, f) for f in dcmp.right_only],
|
||||
}
|
||||
for sub_dcmp in dcmp.subdirs.values():
|
||||
for k, v in recursiveDiff(sub_dcmp).items():
|
||||
diff[k] += v
|
||||
|
|
@ -60,9 +59,13 @@ class TestPelican(LoggedTestCase):
|
|||
|
||||
def assertDirsEqual(self, left_path, right_path):
|
||||
out, err = subprocess.Popen(
|
||||
['git', 'diff', '--no-ext-diff', '--exit-code', '-w', left_path, right_path],
|
||||
env={str('PAGER'): str('')}, stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
['git', 'diff', '--no-ext-diff', '--exit-code',
|
||||
'-w', left_path, right_path],
|
||||
env={str('PAGER'): str('')},
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE
|
||||
).communicate()
|
||||
|
||||
def ignorable_git_crlf_errors(line):
|
||||
# Work around for running tests on Windows
|
||||
for msg in [
|
||||
|
|
@ -85,9 +88,11 @@ class TestPelican(LoggedTestCase):
|
|||
pelican = Pelican(settings=read_settings(path=None))
|
||||
generator_classes = pelican.get_generator_classes()
|
||||
|
||||
self.assertTrue(generator_classes[-1] is StaticGenerator,
|
||||
self.assertTrue(
|
||||
generator_classes[-1] is StaticGenerator,
|
||||
"StaticGenerator must be the last generator, but it isn't!")
|
||||
self.assertIsInstance(generator_classes, collections.Sequence,
|
||||
self.assertIsInstance(
|
||||
generator_classes, collections.Sequence,
|
||||
"get_generator_classes() must return a Sequence to preserve order")
|
||||
|
||||
def test_basic_generation_works(self):
|
||||
|
|
@ -98,10 +103,11 @@ class TestPelican(LoggedTestCase):
|
|||
'OUTPUT_PATH': self.temp_path,
|
||||
'CACHE_PATH': self.temp_cache,
|
||||
'LOCALE': locale.normalize('en_US'),
|
||||
})
|
||||
})
|
||||
pelican = Pelican(settings=settings)
|
||||
mute(True)(pelican.run)()
|
||||
self.assertDirsEqual(self.temp_path, os.path.join(OUTPUT_PATH, 'basic'))
|
||||
self.assertDirsEqual(
|
||||
self.temp_path, os.path.join(OUTPUT_PATH, 'basic'))
|
||||
self.assertLogCountEqual(
|
||||
count=3,
|
||||
msg="Unable to find.*skipping url replacement",
|
||||
|
|
@ -114,10 +120,11 @@ class TestPelican(LoggedTestCase):
|
|||
'OUTPUT_PATH': self.temp_path,
|
||||
'CACHE_PATH': self.temp_cache,
|
||||
'LOCALE': locale.normalize('en_US'),
|
||||
})
|
||||
})
|
||||
pelican = Pelican(settings=settings)
|
||||
mute(True)(pelican.run)()
|
||||
self.assertDirsEqual(self.temp_path, os.path.join(OUTPUT_PATH, 'custom'))
|
||||
self.assertDirsEqual(
|
||||
self.temp_path, os.path.join(OUTPUT_PATH, 'custom'))
|
||||
|
||||
@unittest.skipUnless(locale_available('fr_FR.UTF-8') or
|
||||
locale_available('French'), 'French locale needed')
|
||||
|
|
@ -133,10 +140,11 @@ class TestPelican(LoggedTestCase):
|
|||
'OUTPUT_PATH': self.temp_path,
|
||||
'CACHE_PATH': self.temp_cache,
|
||||
'LOCALE': our_locale,
|
||||
})
|
||||
})
|
||||
pelican = Pelican(settings=settings)
|
||||
mute(True)(pelican.run)()
|
||||
self.assertDirsEqual(self.temp_path, os.path.join(OUTPUT_PATH, 'custom_locale'))
|
||||
self.assertDirsEqual(
|
||||
self.temp_path, os.path.join(OUTPUT_PATH, 'custom_locale'))
|
||||
|
||||
def test_theme_static_paths_copy(self):
|
||||
# the same thing with a specified set of settings should work
|
||||
|
|
@ -146,8 +154,9 @@ class TestPelican(LoggedTestCase):
|
|||
'CACHE_PATH': self.temp_cache,
|
||||
'THEME_STATIC_PATHS': [os.path.join(SAMPLES_PATH, 'very'),
|
||||
os.path.join(SAMPLES_PATH, 'kinda'),
|
||||
os.path.join(SAMPLES_PATH, 'theme_standard')]
|
||||
})
|
||||
os.path.join(SAMPLES_PATH,
|
||||
'theme_standard')]
|
||||
})
|
||||
pelican = Pelican(settings=settings)
|
||||
mute(True)(pelican.run)()
|
||||
theme_output = os.path.join(self.temp_path, 'theme')
|
||||
|
|
@ -165,8 +174,9 @@ class TestPelican(LoggedTestCase):
|
|||
'PATH': INPUT_PATH,
|
||||
'OUTPUT_PATH': self.temp_path,
|
||||
'CACHE_PATH': self.temp_cache,
|
||||
'THEME_STATIC_PATHS': [os.path.join(SAMPLES_PATH, 'theme_standard')]
|
||||
})
|
||||
'THEME_STATIC_PATHS': [os.path.join(SAMPLES_PATH,
|
||||
'theme_standard')]
|
||||
})
|
||||
|
||||
pelican = Pelican(settings=settings)
|
||||
mute(True)(pelican.run)()
|
||||
|
|
@ -184,9 +194,9 @@ class TestPelican(LoggedTestCase):
|
|||
'WRITE_SELECTED': [
|
||||
os.path.join(self.temp_path, 'oh-yeah.html'),
|
||||
os.path.join(self.temp_path, 'categories.html'),
|
||||
],
|
||||
],
|
||||
'LOCALE': locale.normalize('en_US'),
|
||||
})
|
||||
})
|
||||
pelican = Pelican(settings=settings)
|
||||
logger = logging.getLogger()
|
||||
orig_level = logger.getEffectiveLevel()
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals, print_function
|
||||
from __future__ import print_function, unicode_literals
|
||||
|
||||
import os
|
||||
|
||||
from pelican import readers
|
||||
from pelican.tests.support import get_settings, unittest
|
||||
from pelican.utils import SafeDatetime
|
||||
from pelican.tests.support import unittest, get_settings
|
||||
|
||||
|
||||
CUR_DIR = os.path.dirname(__file__)
|
||||
CONTENT_PATH = os.path.join(CUR_DIR, 'content')
|
||||
|
|
@ -29,22 +30,26 @@ class ReaderTest(unittest.TestCase):
|
|||
self.assertEqual(
|
||||
value,
|
||||
real_value,
|
||||
'Expected %s to have value %s, but was %s' % (key, value, real_value))
|
||||
'Expected %s to have value %s, but was %s' %
|
||||
(key, value, real_value))
|
||||
else:
|
||||
self.fail(
|
||||
'Expected %s to have value %s, but was not in Dict' % (key, value))
|
||||
'Expected %s to have value %s, but was not in Dict' %
|
||||
(key, value))
|
||||
|
||||
|
||||
class TestAssertDictHasSubset(ReaderTest):
|
||||
def setUp(self):
|
||||
self.dictionary = {
|
||||
'key-a' : 'val-a',
|
||||
'key-b' : 'val-b'}
|
||||
'key-a': 'val-a',
|
||||
'key-b': 'val-b'
|
||||
}
|
||||
|
||||
def tearDown(self):
|
||||
self.dictionary = None
|
||||
|
||||
def test_subset(self):
|
||||
self.assertDictHasSubset(self.dictionary, {'key-a':'val-a'})
|
||||
self.assertDictHasSubset(self.dictionary, {'key-a': 'val-a'})
|
||||
|
||||
def test_equal(self):
|
||||
self.assertDictHasSubset(self.dictionary, self.dictionary)
|
||||
|
|
@ -54,18 +59,17 @@ class TestAssertDictHasSubset(ReaderTest):
|
|||
AssertionError,
|
||||
'Expected.*key-c.*to have value.*val-c.*but was not in Dict',
|
||||
self.assertDictHasSubset,
|
||||
self.dictionary,
|
||||
{'key-c':'val-c'}
|
||||
)
|
||||
self.dictionary,
|
||||
{'key-c': 'val-c'})
|
||||
|
||||
def test_fail_wrong_val(self):
|
||||
self.assertRaisesRegexp(
|
||||
AssertionError,
|
||||
'Expected .*key-a.* to have value .*val-b.* but was .*val-a.*',
|
||||
self.assertDictHasSubset,
|
||||
self.dictionary,
|
||||
{'key-a':'val-b'}
|
||||
)
|
||||
self.dictionary,
|
||||
{'key-a': 'val-b'})
|
||||
|
||||
|
||||
class DefaultReaderTest(ReaderTest):
|
||||
|
||||
|
|
@ -153,17 +157,17 @@ class RstReaderTest(ReaderTest):
|
|||
'(?P<date>\d{4}-\d{2}-\d{2})'
|
||||
'_(?P<Slug>.*)'
|
||||
'#(?P<MyMeta>.*)-(?P<author>.*)'
|
||||
),
|
||||
),
|
||||
EXTRA_PATH_METADATA={
|
||||
input_with_metadata: {
|
||||
'key-1a': 'value-1a',
|
||||
'key-1b': 'value-1b'
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
expected_metadata = {
|
||||
'category': 'yeah',
|
||||
'author' : 'Alexis Métaireau',
|
||||
'author': 'Alexis Métaireau',
|
||||
'title': 'Rst with filename metadata',
|
||||
'date': SafeDatetime(2012, 11, 29),
|
||||
'slug': 'rst_w_filename_meta',
|
||||
|
|
@ -179,38 +183,41 @@ class RstReaderTest(ReaderTest):
|
|||
path=input_file_path_without_metadata,
|
||||
EXTRA_PATH_METADATA={
|
||||
input_file_path_without_metadata: {
|
||||
'author': 'Charlès Overwrite'}
|
||||
'author': 'Charlès Overwrite'
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
expected_without_metadata = {
|
||||
'category' : 'misc',
|
||||
'author' : 'Charlès Overwrite',
|
||||
'title' : 'Article title',
|
||||
'reader' : 'rst',
|
||||
'category': 'misc',
|
||||
'author': 'Charlès Overwrite',
|
||||
'title': 'Article title',
|
||||
'reader': 'rst',
|
||||
}
|
||||
self.assertDictHasSubset(
|
||||
page_without_metadata.metadata,
|
||||
expected_without_metadata)
|
||||
|
||||
def test_article_extra_path_metadata_dont_overwrite(self):
|
||||
#EXTRA_PATH_METADATA['author'] should get ignored
|
||||
#since we don't overwrite already set values
|
||||
# EXTRA_PATH_METADATA['author'] should get ignored
|
||||
# since we don't overwrite already set values
|
||||
input_file_path = '2012-11-29_rst_w_filename_meta#foo-bar.rst'
|
||||
page = self.read_file(
|
||||
path=input_file_path,
|
||||
FILENAME_METADATA=(
|
||||
'(?P<date>\d{4}-\d{2}-\d{2})'
|
||||
'_(?P<Slug>.*)'
|
||||
'#(?P<MyMeta>.*)-(?P<orginalauthor>.*)'),
|
||||
'#(?P<MyMeta>.*)-(?P<orginalauthor>.*)'
|
||||
),
|
||||
EXTRA_PATH_METADATA={
|
||||
input_file_path: {
|
||||
'author': 'Charlès Overwrite',
|
||||
'key-1b': 'value-1b'}
|
||||
'key-1b': 'value-1b'
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
expected = {
|
||||
'category': 'yeah',
|
||||
'author' : 'Alexis Métaireau',
|
||||
'author': 'Alexis Métaireau',
|
||||
'title': 'Rst with filename metadata',
|
||||
'date': SafeDatetime(2012, 11, 29),
|
||||
'slug': 'rst_w_filename_meta',
|
||||
|
|
@ -273,7 +280,7 @@ class RstReaderTest(ReaderTest):
|
|||
# typogrify should be able to ignore user specified tags,
|
||||
# but tries to be clever with widont extension
|
||||
page = self.read_file(path='article.rst', TYPOGRIFY=True,
|
||||
TYPOGRIFY_IGNORE_TAGS = ['p'])
|
||||
TYPOGRIFY_IGNORE_TAGS=['p'])
|
||||
expected = ('<p>THIS is some content. With some stuff to '
|
||||
'"typogrify"...</p>\n<p>Now with added '
|
||||
'support for <abbr title="three letter acronym">'
|
||||
|
|
@ -284,7 +291,7 @@ class RstReaderTest(ReaderTest):
|
|||
# typogrify should ignore code blocks by default because
|
||||
# code blocks are composed inside the pre tag
|
||||
page = self.read_file(path='article_with_code_block.rst',
|
||||
TYPOGRIFY=True)
|
||||
TYPOGRIFY=True)
|
||||
|
||||
expected = ('<p>An article with some code</p>\n'
|
||||
'<div class="highlight"><pre><span class="n">x</span>'
|
||||
|
|
@ -292,13 +299,17 @@ class RstReaderTest(ReaderTest):
|
|||
' <span class="n">y</span>\n</pre></div>\n'
|
||||
'<p>A block quote:</p>\n<blockquote>\nx '
|
||||
'<span class="amp">&</span> y</blockquote>\n'
|
||||
'<p>Normal:\nx <span class="amp">&</span> y</p>\n')
|
||||
'<p>Normal:\nx'
|
||||
' <span class="amp">&</span>'
|
||||
' y'
|
||||
'</p>\n')
|
||||
|
||||
self.assertEqual(page.content, expected)
|
||||
|
||||
# instruct typogrify to also ignore blockquotes
|
||||
page = self.read_file(path='article_with_code_block.rst',
|
||||
TYPOGRIFY=True, TYPOGRIFY_IGNORE_TAGS = ['blockquote'])
|
||||
TYPOGRIFY=True,
|
||||
TYPOGRIFY_IGNORE_TAGS=['blockquote'])
|
||||
|
||||
expected = ('<p>An article with some code</p>\n'
|
||||
'<div class="highlight"><pre><span class="n">x</span>'
|
||||
|
|
@ -306,7 +317,10 @@ class RstReaderTest(ReaderTest):
|
|||
' <span class="n">y</span>\n</pre></div>\n'
|
||||
'<p>A block quote:</p>\n<blockquote>\nx '
|
||||
'& y</blockquote>\n'
|
||||
'<p>Normal:\nx <span class="amp">&</span> y</p>\n')
|
||||
'<p>Normal:\nx'
|
||||
' <span class="amp">&</span>'
|
||||
' y'
|
||||
'</p>\n')
|
||||
|
||||
self.assertEqual(page.content, expected)
|
||||
except ImportError:
|
||||
|
|
@ -339,6 +353,7 @@ class RstReaderTest(ReaderTest):
|
|||
|
||||
self.assertDictHasSubset(page.metadata, expected)
|
||||
|
||||
|
||||
@unittest.skipUnless(readers.Markdown, "markdown isn't installed")
|
||||
class MdReaderTest(ReaderTest):
|
||||
|
||||
|
|
@ -400,7 +415,8 @@ class MdReaderTest(ReaderTest):
|
|||
'modified': SafeDatetime(2012, 11, 1),
|
||||
'multiline': [
|
||||
'Line Metadata should be handle properly.',
|
||||
'See syntax of Meta-Data extension of Python Markdown package:',
|
||||
'See syntax of Meta-Data extension of '
|
||||
'Python Markdown package:',
|
||||
'If a line is indented by 4 or more spaces,',
|
||||
'that line is assumed to be an additional line of the value',
|
||||
'for the previous keyword.',
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals, print_function
|
||||
from __future__ import print_function, unicode_literals
|
||||
|
||||
from pelican.tests.support import unittest
|
||||
|
||||
try:
|
||||
from unittest.mock import Mock
|
||||
except ImportError:
|
||||
|
|
@ -7,7 +10,7 @@ except ImportError:
|
|||
from mock import Mock
|
||||
except ImportError:
|
||||
Mock = False
|
||||
from pelican.tests.support import unittest
|
||||
|
||||
|
||||
@unittest.skipUnless(Mock, 'Needs Mock module')
|
||||
class Test_abbr_role(unittest.TestCase):
|
||||
|
|
|
|||
|
|
@ -1,13 +1,15 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals, print_function
|
||||
import copy
|
||||
import os
|
||||
import locale
|
||||
from sys import platform
|
||||
from os.path import dirname, abspath, join
|
||||
from __future__ import print_function, unicode_literals
|
||||
|
||||
from pelican.settings import (read_settings, configure_settings,
|
||||
DEFAULT_CONFIG, DEFAULT_THEME)
|
||||
import copy
|
||||
import locale
|
||||
import os
|
||||
from os.path import abspath, dirname, join
|
||||
from sys import platform
|
||||
|
||||
|
||||
from pelican.settings import (DEFAULT_CONFIG, DEFAULT_THEME,
|
||||
configure_settings, read_settings)
|
||||
from pelican.tests.support import unittest
|
||||
|
||||
|
||||
|
|
@ -28,12 +30,14 @@ class TestSettingsConfiguration(unittest.TestCase):
|
|||
|
||||
def test_overwrite_existing_settings(self):
|
||||
self.assertEqual(self.settings.get('SITENAME'), "Alexis' log")
|
||||
self.assertEqual(self.settings.get('SITEURL'),
|
||||
'http://blog.notmyidea.org')
|
||||
self.assertEqual(
|
||||
self.settings.get('SITEURL'),
|
||||
'http://blog.notmyidea.org')
|
||||
|
||||
def test_keep_default_settings(self):
|
||||
# Keep default settings if not defined.
|
||||
self.assertEqual(self.settings.get('DEFAULT_CATEGORY'),
|
||||
self.assertEqual(
|
||||
self.settings.get('DEFAULT_CATEGORY'),
|
||||
DEFAULT_CONFIG['DEFAULT_CATEGORY'])
|
||||
|
||||
def test_dont_copy_small_keys(self):
|
||||
|
|
@ -69,28 +73,31 @@ class TestSettingsConfiguration(unittest.TestCase):
|
|||
|
||||
def test_static_path_settings_safety(self):
|
||||
# Disallow static paths from being strings
|
||||
settings = {'STATIC_PATHS': 'foo/bar',
|
||||
'THEME_STATIC_PATHS': 'bar/baz',
|
||||
# These 4 settings are required to run configure_settings
|
||||
'PATH': '.',
|
||||
'THEME': DEFAULT_THEME,
|
||||
'SITEURL': 'http://blog.notmyidea.org/',
|
||||
'LOCALE': '',
|
||||
}
|
||||
settings = {
|
||||
'STATIC_PATHS': 'foo/bar',
|
||||
'THEME_STATIC_PATHS': 'bar/baz',
|
||||
# These 4 settings are required to run configure_settings
|
||||
'PATH': '.',
|
||||
'THEME': DEFAULT_THEME,
|
||||
'SITEURL': 'http://blog.notmyidea.org/',
|
||||
'LOCALE': '',
|
||||
}
|
||||
configure_settings(settings)
|
||||
self.assertEqual(settings['STATIC_PATHS'],
|
||||
DEFAULT_CONFIG['STATIC_PATHS'])
|
||||
self.assertEqual(settings['THEME_STATIC_PATHS'],
|
||||
DEFAULT_CONFIG['THEME_STATIC_PATHS'])
|
||||
self.assertEqual(
|
||||
settings['STATIC_PATHS'],
|
||||
DEFAULT_CONFIG['STATIC_PATHS'])
|
||||
self.assertEqual(
|
||||
settings['THEME_STATIC_PATHS'],
|
||||
DEFAULT_CONFIG['THEME_STATIC_PATHS'])
|
||||
|
||||
def test_configure_settings(self):
|
||||
# Manipulations to settings should be applied correctly.
|
||||
settings = {
|
||||
'SITEURL': 'http://blog.notmyidea.org/',
|
||||
'LOCALE': '',
|
||||
'PATH': os.curdir,
|
||||
'THEME': DEFAULT_THEME,
|
||||
}
|
||||
'SITEURL': 'http://blog.notmyidea.org/',
|
||||
'LOCALE': '',
|
||||
'PATH': os.curdir,
|
||||
'THEME': DEFAULT_THEME,
|
||||
}
|
||||
configure_settings(settings)
|
||||
|
||||
# SITEURL should not have a trailing slash
|
||||
|
|
@ -154,7 +161,7 @@ class TestSettingsConfiguration(unittest.TestCase):
|
|||
settings['PATH'] = ''
|
||||
self.assertRaises(Exception, configure_settings, settings)
|
||||
|
||||
# Test nonexistent THEME
|
||||
# Test nonexistent THEME
|
||||
settings['PATH'] = os.curdir
|
||||
settings['THEME'] = 'foo'
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from pelican.urlwrappers import URLWrapper, Tag, Category
|
||||
from pelican.tests.support import unittest
|
||||
from pelican.urlwrappers import Category, Tag, URLWrapper
|
||||
|
||||
|
||||
class TestURLWrapper(unittest.TestCase):
|
||||
def test_ordering(self):
|
||||
|
|
|
|||
|
|
@ -1,20 +1,22 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals, print_function, absolute_import
|
||||
import logging
|
||||
import shutil
|
||||
import os
|
||||
import time
|
||||
from __future__ import absolute_import, print_function, unicode_literals
|
||||
|
||||
import locale
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
import time
|
||||
from sys import platform
|
||||
from tempfile import mkdtemp
|
||||
|
||||
import pytz
|
||||
|
||||
from pelican.generators import TemplatePagesGenerator
|
||||
from pelican.writers import Writer
|
||||
from pelican.settings import read_settings
|
||||
from pelican import utils
|
||||
from pelican.tests.support import get_article, LoggedTestCase, locale_available, unittest
|
||||
from pelican.generators import TemplatePagesGenerator
|
||||
from pelican.settings import read_settings
|
||||
from pelican.tests.support import (LoggedTestCase, get_article,
|
||||
locale_available, unittest)
|
||||
from pelican.writers import Writer
|
||||
|
||||
|
||||
class TestUtils(LoggedTestCase):
|
||||
|
|
@ -72,7 +74,7 @@ class TestUtils(LoggedTestCase):
|
|||
'2012-11-22T22:11:10Z': date_hour_sec_z,
|
||||
'2012-11-22T22:11:10-0500': date_hour_sec_est,
|
||||
'2012-11-22T22:11:10.123Z': date_hour_sec_frac_z,
|
||||
}
|
||||
}
|
||||
|
||||
# examples from http://www.w3.org/TR/NOTE-datetime
|
||||
iso_8601_date = utils.SafeDatetime(year=1997, month=7, day=16)
|
||||
|
|
@ -95,7 +97,6 @@ class TestUtils(LoggedTestCase):
|
|||
# invalid ones
|
||||
invalid_dates = ['2010-110-12', 'yay']
|
||||
|
||||
|
||||
for value, expected in dates.items():
|
||||
self.assertEqual(utils.get_date(value), expected, value)
|
||||
|
||||
|
|
@ -290,7 +291,9 @@ class TestUtils(LoggedTestCase):
|
|||
self.assertEqual(utils.strftime(d, '%d/%m/%Y'), '29/08/2012')
|
||||
|
||||
# RFC 3339
|
||||
self.assertEqual(utils.strftime(d, '%Y-%m-%dT%H:%M:%SZ'),'2012-08-29T00:00:00Z')
|
||||
self.assertEqual(
|
||||
utils.strftime(d, '%Y-%m-%dT%H:%M:%SZ'),
|
||||
'2012-08-29T00:00:00Z')
|
||||
|
||||
# % escaped
|
||||
self.assertEqual(utils.strftime(d, '%d%%%m%%%y'), '29%08%12')
|
||||
|
|
@ -306,8 +309,9 @@ class TestUtils(LoggedTestCase):
|
|||
'Published in 29-08-2012')
|
||||
|
||||
# with non-ascii text
|
||||
self.assertEqual(utils.strftime(d, '%d/%m/%Y Øl trinken beim Besäufnis'),
|
||||
'29/08/2012 Øl trinken beim Besäufnis')
|
||||
self.assertEqual(
|
||||
utils.strftime(d, '%d/%m/%Y Øl trinken beim Besäufnis'),
|
||||
'29/08/2012 Øl trinken beim Besäufnis')
|
||||
|
||||
# alternative formatting options
|
||||
self.assertEqual(utils.strftime(d, '%-d/%-m/%y'), '29/8/12')
|
||||
|
|
@ -316,7 +320,6 @@ class TestUtils(LoggedTestCase):
|
|||
d = utils.SafeDatetime(2012, 8, 9)
|
||||
self.assertEqual(utils.strftime(d, '%-d/%-m/%y'), '9/8/12')
|
||||
|
||||
|
||||
# test the output of utils.strftime in a different locale
|
||||
# Turkish locale
|
||||
@unittest.skipUnless(locale_available('tr_TR.UTF-8') or
|
||||
|
|
@ -339,17 +342,18 @@ class TestUtils(LoggedTestCase):
|
|||
'Çarşamba, 29 Ağustos 2012')
|
||||
|
||||
# with text
|
||||
self.assertEqual(utils.strftime(d, 'Yayınlanma tarihi: %A, %d %B %Y'),
|
||||
self.assertEqual(
|
||||
utils.strftime(d, 'Yayınlanma tarihi: %A, %d %B %Y'),
|
||||
'Yayınlanma tarihi: Çarşamba, 29 Ağustos 2012')
|
||||
|
||||
# non-ascii format candidate (someone might pass it... for some reason)
|
||||
self.assertEqual(utils.strftime(d, '%Y yılında %üretim artışı'),
|
||||
self.assertEqual(
|
||||
utils.strftime(d, '%Y yılında %üretim artışı'),
|
||||
'2012 yılında %üretim artışı')
|
||||
|
||||
# restore locale back
|
||||
locale.setlocale(locale.LC_ALL, old_locale)
|
||||
|
||||
|
||||
# test the output of utils.strftime in a different locale
|
||||
# French locale
|
||||
@unittest.skipUnless(locale_available('fr_FR.UTF-8') or
|
||||
|
|
@ -373,21 +377,28 @@ class TestUtils(LoggedTestCase):
|
|||
self.assertTrue(utils.strftime(d, '%A') in ('mercredi', 'Mercredi'))
|
||||
|
||||
# with text
|
||||
self.assertEqual(utils.strftime(d, 'Écrit le %d %B %Y'),
|
||||
self.assertEqual(
|
||||
utils.strftime(d, 'Écrit le %d %B %Y'),
|
||||
'Écrit le 29 août 2012')
|
||||
|
||||
# non-ascii format candidate (someone might pass it... for some reason)
|
||||
self.assertEqual(utils.strftime(d, '%écrits en %Y'),
|
||||
self.assertEqual(
|
||||
utils.strftime(d, '%écrits en %Y'),
|
||||
'%écrits en 2012')
|
||||
|
||||
# restore locale back
|
||||
locale.setlocale(locale.LC_ALL, old_locale)
|
||||
|
||||
|
||||
def test_maybe_pluralize(self):
|
||||
self.assertEqual(utils.maybe_pluralize(0, 'Article', 'Articles'), '0 Articles')
|
||||
self.assertEqual(utils.maybe_pluralize(1, 'Article', 'Articles'), '1 Article')
|
||||
self.assertEqual(utils.maybe_pluralize(2, 'Article', 'Articles'), '2 Articles')
|
||||
self.assertEqual(
|
||||
utils.maybe_pluralize(0, 'Article', 'Articles'),
|
||||
'0 Articles')
|
||||
self.assertEqual(
|
||||
utils.maybe_pluralize(1, 'Article', 'Articles'),
|
||||
'1 Article')
|
||||
self.assertEqual(
|
||||
utils.maybe_pluralize(2, 'Article', 'Articles'),
|
||||
'2 Articles')
|
||||
|
||||
|
||||
class TestCopy(unittest.TestCase):
|
||||
|
|
@ -435,8 +446,9 @@ class TestCopy(unittest.TestCase):
|
|||
|
||||
def test_copy_file_create_dirs(self):
|
||||
self._create_file('a.txt')
|
||||
utils.copy(os.path.join(self.root_dir, 'a.txt'),
|
||||
os.path.join(self.root_dir, 'b0', 'b1', 'b2', 'b3', 'b.txt'))
|
||||
utils.copy(
|
||||
os.path.join(self.root_dir, 'a.txt'),
|
||||
os.path.join(self.root_dir, 'b0', 'b1', 'b2', 'b3', 'b.txt'))
|
||||
self._exist_dir('b0')
|
||||
self._exist_dir('b0', 'b1')
|
||||
self._exist_dir('b0', 'b1', 'b2')
|
||||
|
|
@ -491,35 +503,39 @@ class TestDateFormatter(unittest.TestCase):
|
|||
template_file.write('date = {{ date|strftime("%A, %d %B %Y") }}')
|
||||
self.date = utils.SafeDatetime(2012, 8, 29)
|
||||
|
||||
|
||||
def tearDown(self):
|
||||
shutil.rmtree(self.temp_content)
|
||||
shutil.rmtree(self.temp_output)
|
||||
# reset locale to default
|
||||
locale.setlocale(locale.LC_ALL, '')
|
||||
|
||||
|
||||
@unittest.skipUnless(locale_available('fr_FR.UTF-8') or
|
||||
locale_available('French'),
|
||||
'French locale needed')
|
||||
def test_french_strftime(self):
|
||||
# This test tries to reproduce an issue that occurred with python3.3 under macos10 only
|
||||
# This test tries to reproduce an issue that
|
||||
# occurred with python3.3 under macos10 only
|
||||
if platform == 'win32':
|
||||
locale.setlocale(locale.LC_ALL, str('French'))
|
||||
else:
|
||||
locale.setlocale(locale.LC_ALL, str('fr_FR.UTF-8'))
|
||||
date = utils.SafeDatetime(2014,8,14)
|
||||
# we compare the lower() dates since macos10 returns "Jeudi" for %A whereas linux reports "jeudi"
|
||||
self.assertEqual( u'jeudi, 14 août 2014', utils.strftime(date, date_format="%A, %d %B %Y").lower() )
|
||||
date = utils.SafeDatetime(2014, 8, 14)
|
||||
# we compare the lower() dates since macos10 returns
|
||||
# "Jeudi" for %A whereas linux reports "jeudi"
|
||||
self.assertEqual(
|
||||
u'jeudi, 14 août 2014',
|
||||
utils.strftime(date, date_format="%A, %d %B %Y").lower())
|
||||
df = utils.DateFormatter()
|
||||
self.assertEqual( u'jeudi, 14 août 2014', df(date, date_format="%A, %d %B %Y").lower() )
|
||||
self.assertEqual(
|
||||
u'jeudi, 14 août 2014',
|
||||
df(date, date_format="%A, %d %B %Y").lower())
|
||||
# Let us now set the global locale to C:
|
||||
locale.setlocale(locale.LC_ALL, str('C'))
|
||||
# DateFormatter should still work as expected since it is the whole point of DateFormatter
|
||||
# DateFormatter should still work as expected
|
||||
# since it is the whole point of DateFormatter
|
||||
# (This is where pre-2014/4/15 code fails on macos10)
|
||||
df_date = df(date, date_format="%A, %d %B %Y").lower()
|
||||
self.assertEqual( u'jeudi, 14 août 2014', df_date )
|
||||
|
||||
self.assertEqual(u'jeudi, 14 août 2014', df_date)
|
||||
|
||||
@unittest.skipUnless(locale_available('fr_FR.UTF-8') or
|
||||
locale_available('French'),
|
||||
|
|
@ -530,9 +546,12 @@ class TestDateFormatter(unittest.TestCase):
|
|||
else:
|
||||
locale_string = 'fr_FR.UTF-8'
|
||||
settings = read_settings(
|
||||
override = {'LOCALE': locale_string,
|
||||
'TEMPLATE_PAGES': {'template/source.html':
|
||||
'generated/file.html'}})
|
||||
override={
|
||||
'LOCALE': locale_string,
|
||||
'TEMPLATE_PAGES': {
|
||||
'template/source.html': 'generated/file.html'
|
||||
}
|
||||
})
|
||||
|
||||
generator = TemplatePagesGenerator(
|
||||
{'date': self.date}, settings,
|
||||
|
|
@ -543,7 +562,7 @@ class TestDateFormatter(unittest.TestCase):
|
|||
generator.generate_output(writer)
|
||||
|
||||
output_path = os.path.join(
|
||||
self.temp_output, 'generated', 'file.html')
|
||||
self.temp_output, 'generated', 'file.html')
|
||||
|
||||
# output file has been generated
|
||||
self.assertTrue(os.path.exists(output_path))
|
||||
|
|
@ -553,7 +572,6 @@ class TestDateFormatter(unittest.TestCase):
|
|||
self.assertEqual(output_file,
|
||||
utils.strftime(self.date, 'date = %A, %d %B %Y'))
|
||||
|
||||
|
||||
@unittest.skipUnless(locale_available('tr_TR.UTF-8') or
|
||||
locale_available('Turkish'),
|
||||
'Turkish locale needed')
|
||||
|
|
@ -563,9 +581,12 @@ class TestDateFormatter(unittest.TestCase):
|
|||
else:
|
||||
locale_string = 'tr_TR.UTF-8'
|
||||
settings = read_settings(
|
||||
override = {'LOCALE': locale_string,
|
||||
'TEMPLATE_PAGES': {'template/source.html':
|
||||
'generated/file.html'}})
|
||||
override={
|
||||
'LOCALE': locale_string,
|
||||
'TEMPLATE_PAGES': {
|
||||
'template/source.html': 'generated/file.html'
|
||||
}
|
||||
})
|
||||
|
||||
generator = TemplatePagesGenerator(
|
||||
{'date': self.date}, settings,
|
||||
|
|
@ -576,7 +597,7 @@ class TestDateFormatter(unittest.TestCase):
|
|||
generator.generate_output(writer)
|
||||
|
||||
output_path = os.path.join(
|
||||
self.temp_output, 'generated', 'file.html')
|
||||
self.temp_output, 'generated', 'file.html')
|
||||
|
||||
# output file has been generated
|
||||
self.assertTrue(os.path.exists(output_path))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue