forked from github/pelican
Fix Windows tests
* Unskip passable tests * Fix broken tests
This commit is contained in:
parent
839629b102
commit
2e482b207b
10 changed files with 58 additions and 41 deletions
|
|
@ -696,7 +696,7 @@ def path_metadata(full_path, source_path, settings=None):
|
|||
# Enforce a trailing slash when checking for parent directories.
|
||||
# This prevents false positives when one file or directory's name
|
||||
# is a prefix of another's.
|
||||
dirpath = os.path.join(path, '')
|
||||
dirpath = posixize_path(os.path.join(path, ''))
|
||||
if source_path == path or source_path.startswith(dirpath):
|
||||
metadata.update(meta)
|
||||
|
||||
|
|
|
|||
|
|
@ -160,6 +160,19 @@ def locale_available(locale_):
|
|||
return True
|
||||
|
||||
|
||||
def can_symlink():
|
||||
res = True
|
||||
try:
|
||||
with temporary_folder() as f:
|
||||
os.symlink(
|
||||
f,
|
||||
os.path.join(f, 'symlink')
|
||||
)
|
||||
except OSError:
|
||||
res = False
|
||||
return res
|
||||
|
||||
|
||||
def get_settings(**kwargs):
|
||||
"""Provide tweaked setting dictionaries for testing
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import locale
|
||||
import os
|
||||
import sys
|
||||
from shutil import copy, rmtree
|
||||
from tempfile import mkdtemp
|
||||
from unittest.mock import MagicMock
|
||||
|
|
@ -7,7 +8,8 @@ from unittest.mock import MagicMock
|
|||
from pelican.generators import (ArticlesGenerator, Generator, PagesGenerator,
|
||||
PelicanTemplateNotFound, StaticGenerator,
|
||||
TemplatePagesGenerator)
|
||||
from pelican.tests.support import get_context, get_settings, unittest
|
||||
from pelican.tests.support import (can_symlink, get_context, get_settings,
|
||||
unittest)
|
||||
from pelican.writers import Writer
|
||||
|
||||
|
||||
|
|
@ -1081,6 +1083,7 @@ class TestStaticGenerator(unittest.TestCase):
|
|||
self.generator.generate_output(None)
|
||||
self.assertTrue(os.path.samefile(self.startfile, self.endfile))
|
||||
|
||||
@unittest.skipUnless(can_symlink(), 'No symlink privilege')
|
||||
def test_can_symlink_when_hardlink_not_possible(self):
|
||||
self.settings['STATIC_CREATE_LINKS'] = True
|
||||
with open(self.startfile, "w") as f:
|
||||
|
|
@ -1088,40 +1091,29 @@ class TestStaticGenerator(unittest.TestCase):
|
|||
os.mkdir(os.path.join(self.temp_output, "static"))
|
||||
self.generator.fallback_to_symlinks = True
|
||||
self.generator.generate_context()
|
||||
try:
|
||||
self.generator.generate_output(None)
|
||||
except OSError as e:
|
||||
# On Windows, possibly others, due to not holding symbolic link
|
||||
# privilege
|
||||
self.skipTest(e)
|
||||
self.generator.generate_output(None)
|
||||
self.assertTrue(os.path.islink(self.endfile))
|
||||
|
||||
@unittest.skipUnless(can_symlink(), 'No symlink privilege')
|
||||
def test_existing_symlink_is_considered_up_to_date(self):
|
||||
self.settings['STATIC_CREATE_LINKS'] = True
|
||||
with open(self.startfile, "w") as f:
|
||||
f.write("staticcontent")
|
||||
os.mkdir(os.path.join(self.temp_output, "static"))
|
||||
try:
|
||||
os.symlink(self.startfile, self.endfile)
|
||||
except OSError as e:
|
||||
# On Windows, possibly others
|
||||
self.skipTest(e)
|
||||
os.symlink(self.startfile, self.endfile)
|
||||
staticfile = MagicMock()
|
||||
staticfile.source_path = self.startfile
|
||||
staticfile.save_as = self.endfile
|
||||
requires_update = self.generator._file_update_required(staticfile)
|
||||
self.assertFalse(requires_update)
|
||||
|
||||
@unittest.skipUnless(can_symlink(), 'No symlink privilege')
|
||||
def test_invalid_symlink_is_overwritten(self):
|
||||
self.settings['STATIC_CREATE_LINKS'] = True
|
||||
with open(self.startfile, "w") as f:
|
||||
f.write("staticcontent")
|
||||
os.mkdir(os.path.join(self.temp_output, "static"))
|
||||
try:
|
||||
os.symlink("invalid", self.endfile)
|
||||
except OSError as e:
|
||||
# On Windows, possibly others
|
||||
self.skipTest(e)
|
||||
os.symlink("invalid", self.endfile)
|
||||
staticfile = MagicMock()
|
||||
staticfile.source_path = self.startfile
|
||||
staticfile.save_as = self.endfile
|
||||
|
|
@ -1131,8 +1123,18 @@ class TestStaticGenerator(unittest.TestCase):
|
|||
self.generator.generate_context()
|
||||
self.generator.generate_output(None)
|
||||
self.assertTrue(os.path.islink(self.endfile))
|
||||
self.assertEqual(os.path.realpath(self.endfile),
|
||||
os.path.realpath(self.startfile))
|
||||
|
||||
# os.path.realpath is broken on Windows before python3.8 for symlinks.
|
||||
# This is a (ugly) workaround.
|
||||
# see: https://bugs.python.org/issue9949
|
||||
if os.name == 'nt' and sys.version_info < (3, 8):
|
||||
def get_real_path(path):
|
||||
return os.readlink(path) if os.path.islink(path) else path
|
||||
else:
|
||||
get_real_path = os.path.realpath
|
||||
|
||||
self.assertEqual(get_real_path(self.endfile),
|
||||
get_real_path(self.startfile))
|
||||
|
||||
def test_delete_existing_file_before_mkdir(self):
|
||||
with open(self.startfile, "w") as f:
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import locale
|
||||
import os
|
||||
import re
|
||||
from posixpath import join as posix_join
|
||||
|
||||
from pelican.settings import DEFAULT_CONFIG
|
||||
from pelican.tests.support import (mute, skipIfNoExecutable, temporary_folder,
|
||||
|
|
@ -448,5 +449,5 @@ class TestWordpressXMLAttachements(unittest.TestCase):
|
|||
self.assertEqual(1, len(locations))
|
||||
directory = locations[0]
|
||||
self.assertTrue(
|
||||
directory.endswith(os.path.join('content', 'article.rst')),
|
||||
directory.endswith(posix_join('content', 'article.rst')),
|
||||
directory)
|
||||
|
|
|
|||
|
|
@ -25,11 +25,10 @@ class TestServer(unittest.TestCase):
|
|||
os.chdir(self.temp_output)
|
||||
|
||||
def tearDown(self):
|
||||
rmtree(self.temp_output)
|
||||
os.chdir(self.old_cwd)
|
||||
rmtree(self.temp_output)
|
||||
|
||||
def test_get_path_that_exists(self):
|
||||
|
||||
handler = ComplexHTTPRequestHandler(MockRequest(), ('0.0.0.0', 8888),
|
||||
self.server)
|
||||
handler.base_path = self.temp_output
|
||||
|
|
|
|||
|
|
@ -136,6 +136,8 @@ class TestSettingsConfiguration(unittest.TestCase):
|
|||
settings['ARTICLE_DIR']
|
||||
settings['PAGE_DIR']
|
||||
|
||||
# locale.getdefaultlocale() is broken on Windows
|
||||
# See: https://bugs.python.org/issue37945
|
||||
@unittest.skipIf(platform == 'win32', "Doesn't work on Windows")
|
||||
def test_default_encoding(self):
|
||||
# Test that the default locale is set if not specified in settings
|
||||
|
|
|
|||
|
|
@ -757,35 +757,32 @@ class TestDateFormatter(unittest.TestCase):
|
|||
|
||||
|
||||
class TestSanitisedJoin(unittest.TestCase):
|
||||
@unittest.skipIf(platform == 'win32',
|
||||
"Different filesystem root on Windows")
|
||||
def test_detect_parent_breakout(self):
|
||||
with self.assertRaisesRegex(
|
||||
RuntimeError,
|
||||
"Attempted to break out of output directory to /foo/test"):
|
||||
"Attempted to break out of output directory to "
|
||||
"(.*?:)?/foo/test"): # (.*?:)? accounts for Windows root
|
||||
utils.sanitised_join(
|
||||
"/foo/bar",
|
||||
"../test"
|
||||
)
|
||||
|
||||
@unittest.skipIf(platform == 'win32',
|
||||
"Different filesystem root on Windows")
|
||||
def test_detect_root_breakout(self):
|
||||
with self.assertRaisesRegex(
|
||||
RuntimeError,
|
||||
"Attempted to break out of output directory to /test"):
|
||||
"Attempted to break out of output directory to "
|
||||
"(.*?:)?/test"): # (.*?:)? accounts for Windows root
|
||||
utils.sanitised_join(
|
||||
"/foo/bar",
|
||||
"/test"
|
||||
)
|
||||
|
||||
@unittest.skipIf(platform == 'win32',
|
||||
"Different filesystem root on Windows")
|
||||
def test_pass_deep_subpaths(self):
|
||||
self.assertEqual(
|
||||
utils.sanitised_join(
|
||||
"/foo/bar",
|
||||
"test"
|
||||
),
|
||||
os.path.join("/foo/bar", "test")
|
||||
utils.posixize_path(
|
||||
os.path.abspath(os.path.join("/foo/bar", "test")))
|
||||
)
|
||||
|
|
|
|||
|
|
@ -728,8 +728,9 @@ def download_attachments(output_path, urls):
|
|||
|
||||
# Generate percent-encoded URL
|
||||
scheme, netloc, path, query, fragment = urlsplit(url)
|
||||
path = quote(path)
|
||||
url = urlunsplit((scheme, netloc, path, query, fragment))
|
||||
if scheme != 'file':
|
||||
path = quote(path)
|
||||
url = urlunsplit((scheme, netloc, path, query, fragment))
|
||||
|
||||
if not os.path.exists(full_path):
|
||||
os.makedirs(full_path)
|
||||
|
|
|
|||
|
|
@ -27,8 +27,10 @@ logger = logging.getLogger(__name__)
|
|||
|
||||
|
||||
def sanitised_join(base_directory, *parts):
|
||||
joined = os.path.abspath(os.path.join(base_directory, *parts))
|
||||
if not joined.startswith(os.path.abspath(base_directory)):
|
||||
joined = posixize_path(
|
||||
os.path.abspath(os.path.join(base_directory, *parts)))
|
||||
base = posixize_path(os.path.abspath(base_directory))
|
||||
if not joined.startswith(base):
|
||||
raise RuntimeError(
|
||||
"Attempted to break out of output directory to {}".format(
|
||||
joined
|
||||
|
|
@ -391,10 +393,9 @@ def get_relative_path(path):
|
|||
|
||||
def path_to_url(path):
|
||||
"""Return the URL corresponding to a given path."""
|
||||
if os.sep == '/':
|
||||
return path
|
||||
else:
|
||||
return '/'.join(split_all(path))
|
||||
if path is not None:
|
||||
path = posixize_path(path)
|
||||
return path
|
||||
|
||||
|
||||
def posixize_path(rel_path):
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import logging
|
||||
import os
|
||||
from posixpath import join as posix_join
|
||||
from urllib.parse import urljoin
|
||||
|
||||
from feedgenerator import Atom1Feed, Rss201rev2Feed, get_tag_uri
|
||||
|
|
@ -25,7 +26,7 @@ class Writer:
|
|||
|
||||
# See Content._link_replacer for details
|
||||
if self.settings['RELATIVE_URLS']:
|
||||
self.urljoiner = os.path.join
|
||||
self.urljoiner = posix_join
|
||||
else:
|
||||
self.urljoiner = lambda base, url: urljoin(
|
||||
base if base.endswith('/') else base + '/', url)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue