added podman, json and yaml
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,754 @@
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
from unittest import mock
|
||||
|
||||
from mkdocs.structure.files import File, Files, _filter_paths, _sort_files, get_files
|
||||
from mkdocs.tests.base import PathAssertionMixin, load_config, tempdir
|
||||
|
||||
|
||||
class TestFiles(PathAssertionMixin, unittest.TestCase):
|
||||
def test_file_eq(self):
|
||||
file = File('a.md', '/path/to/docs', '/path/to/site', use_directory_urls=False)
|
||||
self.assertTrue(
|
||||
file == File('a.md', '/path/to/docs', '/path/to/site', use_directory_urls=False)
|
||||
)
|
||||
|
||||
def test_file_ne(self):
|
||||
file = File('a.md', '/path/to/docs', '/path/to/site', use_directory_urls=False)
|
||||
# Different filename
|
||||
self.assertTrue(
|
||||
file != File('b.md', '/path/to/docs', '/path/to/site', use_directory_urls=False)
|
||||
)
|
||||
# Different src_path
|
||||
self.assertTrue(
|
||||
file != File('a.md', '/path/to/other', '/path/to/site', use_directory_urls=False)
|
||||
)
|
||||
# Different URL
|
||||
self.assertTrue(
|
||||
file != File('a.md', '/path/to/docs', '/path/to/site', use_directory_urls=True)
|
||||
)
|
||||
|
||||
@unittest.skipUnless(sys.platform.startswith("win"), "requires Windows")
|
||||
def test_src_path_windows(self):
|
||||
f = File('foo\\a.md', '/path/to/docs', '/path/to/site', use_directory_urls=False)
|
||||
self.assertEqual(f.src_uri, 'foo/a.md')
|
||||
self.assertEqual(f.src_path, 'foo\\a.md')
|
||||
f.src_uri = 'foo/b.md'
|
||||
self.assertEqual(f.src_uri, 'foo/b.md')
|
||||
self.assertEqual(f.src_path, 'foo\\b.md')
|
||||
f.src_path = 'foo/c.md'
|
||||
self.assertEqual(f.src_uri, 'foo/c.md')
|
||||
self.assertEqual(f.src_path, 'foo\\c.md')
|
||||
f.src_path = 'foo\\d.md'
|
||||
self.assertEqual(f.src_uri, 'foo/d.md')
|
||||
self.assertEqual(f.src_path, 'foo\\d.md')
|
||||
f.src_uri = 'foo\\e.md'
|
||||
self.assertEqual(f.src_uri, 'foo\\e.md')
|
||||
self.assertEqual(f.src_path, 'foo\\e.md')
|
||||
|
||||
def test_sort_files(self):
|
||||
self.assertEqual(
|
||||
_sort_files(['b.md', 'bb.md', 'a.md', 'index.md', 'aa.md']),
|
||||
['index.md', 'a.md', 'aa.md', 'b.md', 'bb.md'],
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
_sort_files(['b.md', 'index.html', 'a.md', 'index.md']),
|
||||
['index.html', 'index.md', 'a.md', 'b.md'],
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
_sort_files(['a.md', 'index.md', 'b.md', 'index.html']),
|
||||
['index.md', 'index.html', 'a.md', 'b.md'],
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
_sort_files(['.md', '_.md', 'a.md', 'index.md', '1.md']),
|
||||
['index.md', '.md', '1.md', '_.md', 'a.md'],
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
_sort_files(['a.md', 'b.md', 'a.md']),
|
||||
['a.md', 'a.md', 'b.md'],
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
_sort_files(['A.md', 'B.md', 'README.md']),
|
||||
['README.md', 'A.md', 'B.md'],
|
||||
)
|
||||
|
||||
def test_md_file(self):
|
||||
f = File('foo.md', '/path/to/docs', '/path/to/site', use_directory_urls=False)
|
||||
self.assertEqual(f.src_uri, 'foo.md')
|
||||
self.assertPathsEqual(f.abs_src_path, '/path/to/docs/foo.md')
|
||||
self.assertEqual(f.dest_uri, 'foo.html')
|
||||
self.assertPathsEqual(f.abs_dest_path, '/path/to/site/foo.html')
|
||||
self.assertEqual(f.url, 'foo.html')
|
||||
self.assertEqual(f.name, 'foo')
|
||||
self.assertTrue(f.is_documentation_page())
|
||||
self.assertFalse(f.is_static_page())
|
||||
self.assertFalse(f.is_media_file())
|
||||
self.assertFalse(f.is_javascript())
|
||||
self.assertFalse(f.is_css())
|
||||
|
||||
def test_md_file_use_directory_urls(self):
|
||||
f = File('foo.md', '/path/to/docs', '/path/to/site', use_directory_urls=True)
|
||||
self.assertEqual(f.src_uri, 'foo.md')
|
||||
self.assertPathsEqual(f.abs_src_path, '/path/to/docs/foo.md')
|
||||
self.assertEqual(f.dest_uri, 'foo/index.html')
|
||||
self.assertPathsEqual(f.abs_dest_path, '/path/to/site/foo/index.html')
|
||||
self.assertEqual(f.url, 'foo/')
|
||||
self.assertEqual(f.name, 'foo')
|
||||
self.assertTrue(f.is_documentation_page())
|
||||
self.assertFalse(f.is_static_page())
|
||||
self.assertFalse(f.is_media_file())
|
||||
self.assertFalse(f.is_javascript())
|
||||
self.assertFalse(f.is_css())
|
||||
|
||||
def test_md_file_nested(self):
|
||||
f = File('foo/bar.md', '/path/to/docs', '/path/to/site', use_directory_urls=False)
|
||||
self.assertEqual(f.src_uri, 'foo/bar.md')
|
||||
self.assertPathsEqual(f.abs_src_path, '/path/to/docs/foo/bar.md')
|
||||
self.assertEqual(f.dest_uri, 'foo/bar.html')
|
||||
self.assertPathsEqual(f.abs_dest_path, '/path/to/site/foo/bar.html')
|
||||
self.assertEqual(f.url, 'foo/bar.html')
|
||||
self.assertEqual(f.name, 'bar')
|
||||
self.assertTrue(f.is_documentation_page())
|
||||
self.assertFalse(f.is_static_page())
|
||||
self.assertFalse(f.is_media_file())
|
||||
self.assertFalse(f.is_javascript())
|
||||
self.assertFalse(f.is_css())
|
||||
|
||||
def test_md_file_nested_use_directory_urls(self):
|
||||
f = File('foo/bar.md', '/path/to/docs', '/path/to/site', use_directory_urls=True)
|
||||
self.assertEqual(f.src_uri, 'foo/bar.md')
|
||||
self.assertPathsEqual(f.abs_src_path, '/path/to/docs/foo/bar.md')
|
||||
self.assertEqual(f.dest_uri, 'foo/bar/index.html')
|
||||
self.assertPathsEqual(f.abs_dest_path, '/path/to/site/foo/bar/index.html')
|
||||
self.assertEqual(f.url, 'foo/bar/')
|
||||
self.assertEqual(f.name, 'bar')
|
||||
self.assertTrue(f.is_documentation_page())
|
||||
self.assertFalse(f.is_static_page())
|
||||
self.assertFalse(f.is_media_file())
|
||||
self.assertFalse(f.is_javascript())
|
||||
self.assertFalse(f.is_css())
|
||||
|
||||
def test_md_index_file(self):
|
||||
f = File('index.md', '/path/to/docs', '/path/to/site', use_directory_urls=False)
|
||||
self.assertEqual(f.src_uri, 'index.md')
|
||||
self.assertPathsEqual(f.abs_src_path, '/path/to/docs/index.md')
|
||||
self.assertEqual(f.dest_uri, 'index.html')
|
||||
self.assertPathsEqual(f.abs_dest_path, '/path/to/site/index.html')
|
||||
self.assertEqual(f.url, 'index.html')
|
||||
self.assertEqual(f.name, 'index')
|
||||
self.assertTrue(f.is_documentation_page())
|
||||
self.assertFalse(f.is_static_page())
|
||||
self.assertFalse(f.is_media_file())
|
||||
self.assertFalse(f.is_javascript())
|
||||
self.assertFalse(f.is_css())
|
||||
|
||||
def test_md_readme_index_file(self):
|
||||
f = File('README.md', '/path/to/docs', '/path/to/site', use_directory_urls=False)
|
||||
self.assertEqual(f.src_uri, 'README.md')
|
||||
self.assertPathsEqual(f.abs_src_path, '/path/to/docs/README.md')
|
||||
self.assertEqual(f.dest_uri, 'index.html')
|
||||
self.assertPathsEqual(f.abs_dest_path, '/path/to/site/index.html')
|
||||
self.assertEqual(f.url, 'index.html')
|
||||
self.assertEqual(f.name, 'index')
|
||||
self.assertTrue(f.is_documentation_page())
|
||||
self.assertFalse(f.is_static_page())
|
||||
self.assertFalse(f.is_media_file())
|
||||
self.assertFalse(f.is_javascript())
|
||||
self.assertFalse(f.is_css())
|
||||
|
||||
def test_md_index_file_use_directory_urls(self):
|
||||
f = File('index.md', '/path/to/docs', '/path/to/site', use_directory_urls=True)
|
||||
self.assertEqual(f.src_uri, 'index.md')
|
||||
self.assertPathsEqual(f.abs_src_path, '/path/to/docs/index.md')
|
||||
self.assertEqual(f.dest_uri, 'index.html')
|
||||
self.assertPathsEqual(f.abs_dest_path, '/path/to/site/index.html')
|
||||
self.assertEqual(f.url, './')
|
||||
self.assertEqual(f.name, 'index')
|
||||
self.assertTrue(f.is_documentation_page())
|
||||
self.assertFalse(f.is_static_page())
|
||||
self.assertFalse(f.is_media_file())
|
||||
self.assertFalse(f.is_javascript())
|
||||
self.assertFalse(f.is_css())
|
||||
|
||||
def test_md_readme_index_file_use_directory_urls(self):
|
||||
f = File('README.md', '/path/to/docs', '/path/to/site', use_directory_urls=True)
|
||||
self.assertEqual(f.src_uri, 'README.md')
|
||||
self.assertPathsEqual(f.abs_src_path, '/path/to/docs/README.md')
|
||||
self.assertEqual(f.dest_uri, 'index.html')
|
||||
self.assertPathsEqual(f.abs_dest_path, '/path/to/site/index.html')
|
||||
self.assertEqual(f.url, './')
|
||||
self.assertEqual(f.name, 'index')
|
||||
self.assertTrue(f.is_documentation_page())
|
||||
self.assertFalse(f.is_static_page())
|
||||
self.assertFalse(f.is_media_file())
|
||||
self.assertFalse(f.is_javascript())
|
||||
self.assertFalse(f.is_css())
|
||||
|
||||
def test_md_index_file_nested(self):
|
||||
f = File('foo/index.md', '/path/to/docs', '/path/to/site', use_directory_urls=False)
|
||||
self.assertEqual(f.src_uri, 'foo/index.md')
|
||||
self.assertPathsEqual(f.abs_src_path, '/path/to/docs/foo/index.md')
|
||||
self.assertEqual(f.dest_uri, 'foo/index.html')
|
||||
self.assertPathsEqual(f.abs_dest_path, '/path/to/site/foo/index.html')
|
||||
self.assertEqual(f.url, 'foo/index.html')
|
||||
self.assertEqual(f.name, 'index')
|
||||
self.assertTrue(f.is_documentation_page())
|
||||
self.assertFalse(f.is_static_page())
|
||||
self.assertFalse(f.is_media_file())
|
||||
self.assertFalse(f.is_javascript())
|
||||
self.assertFalse(f.is_css())
|
||||
|
||||
def test_md_index_file_nested_use_directory_urls(self):
|
||||
f = File('foo/index.md', '/path/to/docs', '/path/to/site', use_directory_urls=True)
|
||||
self.assertEqual(f.src_uri, 'foo/index.md')
|
||||
self.assertPathsEqual(f.abs_src_path, '/path/to/docs/foo/index.md')
|
||||
self.assertEqual(f.dest_uri, 'foo/index.html')
|
||||
self.assertPathsEqual(f.abs_dest_path, '/path/to/site/foo/index.html')
|
||||
self.assertEqual(f.url, 'foo/')
|
||||
self.assertEqual(f.name, 'index')
|
||||
self.assertTrue(f.is_documentation_page())
|
||||
self.assertFalse(f.is_static_page())
|
||||
self.assertFalse(f.is_media_file())
|
||||
self.assertFalse(f.is_javascript())
|
||||
self.assertFalse(f.is_css())
|
||||
|
||||
def test_static_file(self):
|
||||
f = File('foo/bar.html', '/path/to/docs', '/path/to/site', use_directory_urls=False)
|
||||
self.assertEqual(f.src_uri, 'foo/bar.html')
|
||||
self.assertPathsEqual(f.abs_src_path, '/path/to/docs/foo/bar.html')
|
||||
self.assertEqual(f.dest_uri, 'foo/bar.html')
|
||||
self.assertPathsEqual(f.abs_dest_path, '/path/to/site/foo/bar.html')
|
||||
self.assertEqual(f.url, 'foo/bar.html')
|
||||
self.assertEqual(f.name, 'bar')
|
||||
self.assertFalse(f.is_documentation_page())
|
||||
self.assertTrue(f.is_static_page())
|
||||
self.assertFalse(f.is_media_file())
|
||||
self.assertFalse(f.is_javascript())
|
||||
self.assertFalse(f.is_css())
|
||||
|
||||
def test_static_file_use_directory_urls(self):
|
||||
f = File('foo/bar.html', '/path/to/docs', '/path/to/site', use_directory_urls=True)
|
||||
self.assertEqual(f.src_uri, 'foo/bar.html')
|
||||
self.assertPathsEqual(f.abs_src_path, '/path/to/docs/foo/bar.html')
|
||||
self.assertEqual(f.dest_uri, 'foo/bar.html')
|
||||
self.assertPathsEqual(f.abs_dest_path, '/path/to/site/foo/bar.html')
|
||||
self.assertEqual(f.url, 'foo/bar.html')
|
||||
self.assertEqual(f.name, 'bar')
|
||||
self.assertFalse(f.is_documentation_page())
|
||||
self.assertTrue(f.is_static_page())
|
||||
self.assertFalse(f.is_media_file())
|
||||
self.assertFalse(f.is_javascript())
|
||||
self.assertFalse(f.is_css())
|
||||
|
||||
def test_media_file(self):
|
||||
f = File('foo/bar.jpg', '/path/to/docs', '/path/to/site', use_directory_urls=False)
|
||||
self.assertEqual(f.src_uri, 'foo/bar.jpg')
|
||||
self.assertPathsEqual(f.abs_src_path, '/path/to/docs/foo/bar.jpg')
|
||||
self.assertEqual(f.dest_uri, 'foo/bar.jpg')
|
||||
self.assertPathsEqual(f.abs_dest_path, '/path/to/site/foo/bar.jpg')
|
||||
self.assertEqual(f.url, 'foo/bar.jpg')
|
||||
self.assertEqual(f.name, 'bar')
|
||||
self.assertFalse(f.is_documentation_page())
|
||||
self.assertFalse(f.is_static_page())
|
||||
self.assertTrue(f.is_media_file())
|
||||
self.assertFalse(f.is_javascript())
|
||||
self.assertFalse(f.is_css())
|
||||
|
||||
def test_media_file_use_directory_urls(self):
|
||||
f = File('foo/bar.jpg', '/path/to/docs', '/path/to/site', use_directory_urls=True)
|
||||
self.assertEqual(f.src_uri, 'foo/bar.jpg')
|
||||
self.assertPathsEqual(f.abs_src_path, '/path/to/docs/foo/bar.jpg')
|
||||
self.assertEqual(f.dest_uri, 'foo/bar.jpg')
|
||||
self.assertPathsEqual(f.abs_dest_path, '/path/to/site/foo/bar.jpg')
|
||||
self.assertEqual(f.url, 'foo/bar.jpg')
|
||||
self.assertEqual(f.name, 'bar')
|
||||
self.assertFalse(f.is_documentation_page())
|
||||
self.assertFalse(f.is_static_page())
|
||||
self.assertTrue(f.is_media_file())
|
||||
self.assertFalse(f.is_javascript())
|
||||
self.assertFalse(f.is_css())
|
||||
|
||||
def test_javascript_file(self):
|
||||
f = File('foo/bar.js', '/path/to/docs', '/path/to/site', use_directory_urls=False)
|
||||
self.assertEqual(f.src_uri, 'foo/bar.js')
|
||||
self.assertPathsEqual(f.abs_src_path, '/path/to/docs/foo/bar.js')
|
||||
self.assertEqual(f.dest_uri, 'foo/bar.js')
|
||||
self.assertPathsEqual(f.abs_dest_path, '/path/to/site/foo/bar.js')
|
||||
self.assertEqual(f.url, 'foo/bar.js')
|
||||
self.assertEqual(f.name, 'bar')
|
||||
self.assertFalse(f.is_documentation_page())
|
||||
self.assertFalse(f.is_static_page())
|
||||
self.assertTrue(f.is_media_file())
|
||||
self.assertTrue(f.is_javascript())
|
||||
self.assertFalse(f.is_css())
|
||||
|
||||
def test_javascript_file_use_directory_urls(self):
|
||||
f = File('foo/bar.js', '/path/to/docs', '/path/to/site', use_directory_urls=True)
|
||||
self.assertEqual(f.src_uri, 'foo/bar.js')
|
||||
self.assertPathsEqual(f.abs_src_path, '/path/to/docs/foo/bar.js')
|
||||
self.assertEqual(f.dest_uri, 'foo/bar.js')
|
||||
self.assertPathsEqual(f.abs_dest_path, '/path/to/site/foo/bar.js')
|
||||
self.assertEqual(f.url, 'foo/bar.js')
|
||||
self.assertEqual(f.name, 'bar')
|
||||
self.assertFalse(f.is_documentation_page())
|
||||
self.assertFalse(f.is_static_page())
|
||||
self.assertTrue(f.is_media_file())
|
||||
self.assertTrue(f.is_javascript())
|
||||
self.assertFalse(f.is_css())
|
||||
|
||||
def test_css_file(self):
|
||||
f = File('foo/bar.css', '/path/to/docs', '/path/to/site', use_directory_urls=False)
|
||||
self.assertEqual(f.src_uri, 'foo/bar.css')
|
||||
self.assertPathsEqual(f.abs_src_path, '/path/to/docs/foo/bar.css')
|
||||
self.assertEqual(f.dest_uri, 'foo/bar.css')
|
||||
self.assertPathsEqual(f.abs_dest_path, '/path/to/site/foo/bar.css')
|
||||
self.assertEqual(f.url, 'foo/bar.css')
|
||||
self.assertEqual(f.name, 'bar')
|
||||
self.assertFalse(f.is_documentation_page())
|
||||
self.assertFalse(f.is_static_page())
|
||||
self.assertTrue(f.is_media_file())
|
||||
self.assertFalse(f.is_javascript())
|
||||
self.assertTrue(f.is_css())
|
||||
|
||||
def test_css_file_use_directory_urls(self):
|
||||
f = File('foo/bar.css', '/path/to/docs', '/path/to/site', use_directory_urls=True)
|
||||
self.assertEqual(f.src_uri, 'foo/bar.css')
|
||||
self.assertPathsEqual(f.abs_src_path, '/path/to/docs/foo/bar.css')
|
||||
self.assertEqual(f.dest_uri, 'foo/bar.css')
|
||||
self.assertPathsEqual(f.abs_dest_path, '/path/to/site/foo/bar.css')
|
||||
self.assertEqual(f.url, 'foo/bar.css')
|
||||
self.assertEqual(f.name, 'bar')
|
||||
self.assertFalse(f.is_documentation_page())
|
||||
self.assertFalse(f.is_static_page())
|
||||
self.assertTrue(f.is_media_file())
|
||||
self.assertFalse(f.is_javascript())
|
||||
self.assertTrue(f.is_css())
|
||||
|
||||
def test_file_name_with_space(self):
|
||||
f = File('foo bar.md', '/path/to/docs', '/path/to/site', use_directory_urls=False)
|
||||
self.assertEqual(f.src_uri, 'foo bar.md')
|
||||
self.assertPathsEqual(f.abs_src_path, '/path/to/docs/foo bar.md')
|
||||
self.assertEqual(f.dest_uri, 'foo bar.html')
|
||||
self.assertPathsEqual(f.abs_dest_path, '/path/to/site/foo bar.html')
|
||||
self.assertEqual(f.url, 'foo%20bar.html')
|
||||
self.assertEqual(f.name, 'foo bar')
|
||||
|
||||
def test_files(self):
|
||||
fs = [
|
||||
File('index.md', '/path/to/docs', '/path/to/site', use_directory_urls=True),
|
||||
File('foo/bar.md', '/path/to/docs', '/path/to/site', use_directory_urls=True),
|
||||
File('foo/bar.html', '/path/to/docs', '/path/to/site', use_directory_urls=True),
|
||||
File('foo/bar.jpg', '/path/to/docs', '/path/to/site', use_directory_urls=True),
|
||||
File('foo/bar.js', '/path/to/docs', '/path/to/site', use_directory_urls=True),
|
||||
File('foo/bar.css', '/path/to/docs', '/path/to/site', use_directory_urls=True),
|
||||
]
|
||||
files = Files(fs)
|
||||
self.assertEqual([f for f in files], fs)
|
||||
self.assertEqual(len(files), 6)
|
||||
self.assertEqual(files.documentation_pages(), [fs[0], fs[1]])
|
||||
self.assertEqual(files.static_pages(), [fs[2]])
|
||||
self.assertEqual(files.media_files(), [fs[3], fs[4], fs[5]])
|
||||
self.assertEqual(files.javascript_files(), [fs[4]])
|
||||
self.assertEqual(files.css_files(), [fs[5]])
|
||||
self.assertEqual(files.get_file_from_path('foo/bar.jpg'), fs[3])
|
||||
self.assertEqual(files.get_file_from_path('foo/bar.jpg'), fs[3])
|
||||
self.assertEqual(files.get_file_from_path('missing.jpg'), None)
|
||||
self.assertTrue(fs[2].src_uri in files.src_uris)
|
||||
self.assertTrue(fs[2].src_uri in files.src_uris)
|
||||
extra_file = File('extra.md', '/path/to/docs', '/path/to/site', use_directory_urls=True)
|
||||
self.assertFalse(extra_file.src_uri in files.src_uris)
|
||||
files.append(extra_file)
|
||||
self.assertEqual(len(files), 7)
|
||||
self.assertTrue(extra_file.src_uri in files.src_uris)
|
||||
self.assertEqual(files.documentation_pages(), [fs[0], fs[1], extra_file])
|
||||
|
||||
@tempdir(
|
||||
files=[
|
||||
'favicon.ico',
|
||||
'index.md',
|
||||
]
|
||||
)
|
||||
@tempdir(
|
||||
files=[
|
||||
'base.html',
|
||||
'favicon.ico',
|
||||
'style.css',
|
||||
'foo.md',
|
||||
'README',
|
||||
'.ignore.txt',
|
||||
'.ignore/file.txt',
|
||||
'foo/.ignore.txt',
|
||||
'foo/.ignore/file.txt',
|
||||
]
|
||||
)
|
||||
def test_add_files_from_theme(self, tdir, ddir):
|
||||
config = load_config(docs_dir=ddir, theme={'name': None, 'custom_dir': tdir})
|
||||
env = config.theme.get_env()
|
||||
files = get_files(config)
|
||||
self.assertEqual(
|
||||
[file.src_path for file in files],
|
||||
['index.md', 'favicon.ico'],
|
||||
)
|
||||
files.add_files_from_theme(env, config)
|
||||
self.assertEqual(
|
||||
[file.src_path for file in files],
|
||||
['index.md', 'favicon.ico', 'style.css'],
|
||||
)
|
||||
# Ensure theme file does not override docs_dir file
|
||||
self.assertEqual(
|
||||
files.get_file_from_path('favicon.ico').abs_src_path,
|
||||
os.path.normpath(os.path.join(ddir, 'favicon.ico')),
|
||||
)
|
||||
|
||||
def test_filter_paths(self):
|
||||
# Root level file
|
||||
self.assertFalse(_filter_paths('foo.md', 'foo.md', False, ['bar.md']))
|
||||
self.assertTrue(_filter_paths('foo.md', 'foo.md', False, ['foo.md']))
|
||||
|
||||
# Nested file
|
||||
self.assertFalse(_filter_paths('foo.md', 'baz/foo.md', False, ['bar.md']))
|
||||
self.assertTrue(_filter_paths('foo.md', 'baz/foo.md', False, ['foo.md']))
|
||||
|
||||
# Wildcard
|
||||
self.assertFalse(_filter_paths('foo.md', 'foo.md', False, ['*.txt']))
|
||||
self.assertTrue(_filter_paths('foo.md', 'foo.md', False, ['*.md']))
|
||||
|
||||
# Root level dir
|
||||
self.assertFalse(_filter_paths('bar', 'bar', True, ['/baz']))
|
||||
self.assertFalse(_filter_paths('bar', 'bar', True, ['/baz/']))
|
||||
self.assertTrue(_filter_paths('bar', 'bar', True, ['/bar']))
|
||||
self.assertTrue(_filter_paths('bar', 'bar', True, ['/bar/']))
|
||||
|
||||
# Nested dir
|
||||
self.assertFalse(_filter_paths('bar', 'foo/bar', True, ['/bar']))
|
||||
self.assertFalse(_filter_paths('bar', 'foo/bar', True, ['/bar/']))
|
||||
self.assertTrue(_filter_paths('bar', 'foo/bar', True, ['bar/']))
|
||||
|
||||
# Files that look like dirs (no extension). Note that `is_dir` is `False`.
|
||||
self.assertFalse(_filter_paths('bar', 'bar', False, ['bar/']))
|
||||
self.assertFalse(_filter_paths('bar', 'foo/bar', False, ['bar/']))
|
||||
|
||||
def test_get_relative_url_use_directory_urls(self):
|
||||
to_files = [
|
||||
'index.md',
|
||||
'foo/index.md',
|
||||
'foo/bar/index.md',
|
||||
'foo/bar/baz/index.md',
|
||||
'foo.md',
|
||||
'foo/bar.md',
|
||||
'foo/bar/baz.md',
|
||||
]
|
||||
|
||||
to_file_urls = [
|
||||
'./',
|
||||
'foo/',
|
||||
'foo/bar/',
|
||||
'foo/bar/baz/',
|
||||
'foo/',
|
||||
'foo/bar/',
|
||||
'foo/bar/baz/',
|
||||
]
|
||||
|
||||
from_file = File('img.jpg', '/path/to/docs', '/path/to/site', use_directory_urls=True)
|
||||
expected = [
|
||||
'img.jpg', # img.jpg relative to .
|
||||
'../img.jpg', # img.jpg relative to foo/
|
||||
'../../img.jpg', # img.jpg relative to foo/bar/
|
||||
'../../../img.jpg', # img.jpg relative to foo/bar/baz/
|
||||
'../img.jpg', # img.jpg relative to foo
|
||||
'../../img.jpg', # img.jpg relative to foo/bar
|
||||
'../../../img.jpg', # img.jpg relative to foo/bar/baz
|
||||
]
|
||||
|
||||
for i, filename in enumerate(to_files):
|
||||
file = File(filename, '/path/to/docs', '/path/to/site', use_directory_urls=True)
|
||||
self.assertEqual(from_file.url, 'img.jpg')
|
||||
self.assertEqual(file.url, to_file_urls[i])
|
||||
self.assertEqual(from_file.url_relative_to(file.url), expected[i])
|
||||
self.assertEqual(from_file.url_relative_to(file), expected[i])
|
||||
|
||||
from_file = File('foo/img.jpg', '/path/to/docs', '/path/to/site', use_directory_urls=True)
|
||||
expected = [
|
||||
'foo/img.jpg', # foo/img.jpg relative to .
|
||||
'img.jpg', # foo/img.jpg relative to foo/
|
||||
'../img.jpg', # foo/img.jpg relative to foo/bar/
|
||||
'../../img.jpg', # foo/img.jpg relative to foo/bar/baz/
|
||||
'img.jpg', # foo/img.jpg relative to foo
|
||||
'../img.jpg', # foo/img.jpg relative to foo/bar
|
||||
'../../img.jpg', # foo/img.jpg relative to foo/bar/baz
|
||||
]
|
||||
|
||||
for i, filename in enumerate(to_files):
|
||||
file = File(filename, '/path/to/docs', '/path/to/site', use_directory_urls=True)
|
||||
self.assertEqual(from_file.url, 'foo/img.jpg')
|
||||
self.assertEqual(file.url, to_file_urls[i])
|
||||
self.assertEqual(from_file.url_relative_to(file.url), expected[i])
|
||||
self.assertEqual(from_file.url_relative_to(file), expected[i])
|
||||
|
||||
from_file = File('index.html', '/path/to/docs', '/path/to/site', use_directory_urls=True)
|
||||
expected = [
|
||||
'./', # . relative to .
|
||||
'../', # . relative to foo/
|
||||
'../../', # . relative to foo/bar/
|
||||
'../../../', # . relative to foo/bar/baz/
|
||||
'../', # . relative to foo
|
||||
'../../', # . relative to foo/bar
|
||||
'../../../', # . relative to foo/bar/baz
|
||||
]
|
||||
|
||||
for i, filename in enumerate(to_files):
|
||||
file = File(filename, '/path/to/docs', '/path/to/site', use_directory_urls=True)
|
||||
self.assertEqual(from_file.url, './')
|
||||
self.assertEqual(file.url, to_file_urls[i])
|
||||
self.assertEqual(from_file.url_relative_to(file.url), expected[i])
|
||||
self.assertEqual(from_file.url_relative_to(file), expected[i])
|
||||
|
||||
from_file = File('file.md', '/path/to/docs', '/path/to/site', use_directory_urls=True)
|
||||
expected = [
|
||||
'file/', # file relative to .
|
||||
'../file/', # file relative to foo/
|
||||
'../../file/', # file relative to foo/bar/
|
||||
'../../../file/', # file relative to foo/bar/baz/
|
||||
'../file/', # file relative to foo
|
||||
'../../file/', # file relative to foo/bar
|
||||
'../../../file/', # file relative to foo/bar/baz
|
||||
]
|
||||
|
||||
for i, filename in enumerate(to_files):
|
||||
file = File(filename, '/path/to/docs', '/path/to/site', use_directory_urls=True)
|
||||
self.assertEqual(from_file.url, 'file/')
|
||||
self.assertEqual(file.url, to_file_urls[i])
|
||||
self.assertEqual(from_file.url_relative_to(file.url), expected[i])
|
||||
self.assertEqual(from_file.url_relative_to(file), expected[i])
|
||||
|
||||
def test_get_relative_url(self):
|
||||
to_files = [
|
||||
'index.md',
|
||||
'foo/index.md',
|
||||
'foo/bar/index.md',
|
||||
'foo/bar/baz/index.md',
|
||||
'foo.md',
|
||||
'foo/bar.md',
|
||||
'foo/bar/baz.md',
|
||||
]
|
||||
|
||||
to_file_urls = [
|
||||
'index.html',
|
||||
'foo/index.html',
|
||||
'foo/bar/index.html',
|
||||
'foo/bar/baz/index.html',
|
||||
'foo.html',
|
||||
'foo/bar.html',
|
||||
'foo/bar/baz.html',
|
||||
]
|
||||
|
||||
from_file = File('img.jpg', '/path/to/docs', '/path/to/site', use_directory_urls=False)
|
||||
expected = [
|
||||
'img.jpg', # img.jpg relative to .
|
||||
'../img.jpg', # img.jpg relative to foo/
|
||||
'../../img.jpg', # img.jpg relative to foo/bar/
|
||||
'../../../img.jpg', # img.jpg relative to foo/bar/baz/
|
||||
'img.jpg', # img.jpg relative to foo.html
|
||||
'../img.jpg', # img.jpg relative to foo/bar.html
|
||||
'../../img.jpg', # img.jpg relative to foo/bar/baz.html
|
||||
]
|
||||
|
||||
for i, filename in enumerate(to_files):
|
||||
with self.subTest(from_file=from_file.src_path, to_file=filename):
|
||||
file = File(filename, '/path/to/docs', '/path/to/site', use_directory_urls=False)
|
||||
self.assertEqual(from_file.url, 'img.jpg')
|
||||
self.assertEqual(file.url, to_file_urls[i])
|
||||
self.assertEqual(from_file.url_relative_to(file.url), expected[i])
|
||||
self.assertEqual(from_file.url_relative_to(file), expected[i])
|
||||
|
||||
from_file = File('foo/img.jpg', '/path/to/docs', '/path/to/site', use_directory_urls=False)
|
||||
expected = [
|
||||
'foo/img.jpg', # foo/img.jpg relative to .
|
||||
'img.jpg', # foo/img.jpg relative to foo/
|
||||
'../img.jpg', # foo/img.jpg relative to foo/bar/
|
||||
'../../img.jpg', # foo/img.jpg relative to foo/bar/baz/
|
||||
'foo/img.jpg', # foo/img.jpg relative to foo.html
|
||||
'img.jpg', # foo/img.jpg relative to foo/bar.html
|
||||
'../img.jpg', # foo/img.jpg relative to foo/bar/baz.html
|
||||
]
|
||||
|
||||
for i, filename in enumerate(to_files):
|
||||
with self.subTest(from_file=from_file.src_path, to_file=filename):
|
||||
file = File(filename, '/path/to/docs', '/path/to/site', use_directory_urls=False)
|
||||
self.assertEqual(from_file.url, 'foo/img.jpg')
|
||||
self.assertEqual(file.url, to_file_urls[i])
|
||||
self.assertEqual(from_file.url_relative_to(file.url), expected[i])
|
||||
self.assertEqual(from_file.url_relative_to(file), expected[i])
|
||||
|
||||
from_file = File('index.html', '/path/to/docs', '/path/to/site', use_directory_urls=False)
|
||||
expected = [
|
||||
'index.html', # index.html relative to .
|
||||
'../index.html', # index.html relative to foo/
|
||||
'../../index.html', # index.html relative to foo/bar/
|
||||
'../../../index.html', # index.html relative to foo/bar/baz/
|
||||
'index.html', # index.html relative to foo.html
|
||||
'../index.html', # index.html relative to foo/bar.html
|
||||
'../../index.html', # index.html relative to foo/bar/baz.html
|
||||
]
|
||||
|
||||
for i, filename in enumerate(to_files):
|
||||
with self.subTest(from_file=from_file.src_path, to_file=filename):
|
||||
file = File(filename, '/path/to/docs', '/path/to/site', use_directory_urls=False)
|
||||
self.assertEqual(from_file.url, 'index.html')
|
||||
self.assertEqual(file.url, to_file_urls[i])
|
||||
self.assertEqual(from_file.url_relative_to(file.url), expected[i])
|
||||
self.assertEqual(from_file.url_relative_to(file), expected[i])
|
||||
|
||||
from_file = File('file.html', '/path/to/docs', '/path/to/site', use_directory_urls=False)
|
||||
expected = [
|
||||
'file.html', # file.html relative to .
|
||||
'../file.html', # file.html relative to foo/
|
||||
'../../file.html', # file.html relative to foo/bar/
|
||||
'../../../file.html', # file.html relative to foo/bar/baz/
|
||||
'file.html', # file.html relative to foo.html
|
||||
'../file.html', # file.html relative to foo/bar.html
|
||||
'../../file.html', # file.html relative to foo/bar/baz.html
|
||||
]
|
||||
|
||||
for i, filename in enumerate(to_files):
|
||||
with self.subTest(from_file=from_file.src_path, to_file=filename):
|
||||
file = File(filename, '/path/to/docs', '/path/to/site', use_directory_urls=False)
|
||||
self.assertEqual(from_file.url, 'file.html')
|
||||
self.assertEqual(file.url, to_file_urls[i])
|
||||
self.assertEqual(from_file.url_relative_to(file.url), expected[i])
|
||||
self.assertEqual(from_file.url_relative_to(file), expected[i])
|
||||
|
||||
@tempdir(
|
||||
files=[
|
||||
'index.md',
|
||||
'readme.md',
|
||||
'bar.css',
|
||||
'bar.html',
|
||||
'bar.jpg',
|
||||
'bar.js',
|
||||
'bar.md',
|
||||
'.dotfile',
|
||||
'templates/foo.html',
|
||||
]
|
||||
)
|
||||
def test_get_files(self, tdir):
|
||||
config = load_config(docs_dir=tdir, extra_css=['bar.css'], extra_javascript=['bar.js'])
|
||||
files = get_files(config)
|
||||
expected = ['index.md', 'bar.css', 'bar.html', 'bar.jpg', 'bar.js', 'bar.md', 'readme.md']
|
||||
self.assertIsInstance(files, Files)
|
||||
self.assertEqual(len(files), len(expected))
|
||||
self.assertEqual([f.src_path for f in files], expected)
|
||||
|
||||
@tempdir(
|
||||
files=[
|
||||
'README.md',
|
||||
'foo.md',
|
||||
]
|
||||
)
|
||||
def test_get_files_include_readme_without_index(self, tdir):
|
||||
config = load_config(docs_dir=tdir)
|
||||
files = get_files(config)
|
||||
expected = ['README.md', 'foo.md']
|
||||
self.assertIsInstance(files, Files)
|
||||
self.assertEqual(len(files), len(expected))
|
||||
self.assertEqual([f.src_path for f in files], expected)
|
||||
|
||||
@tempdir(
|
||||
files=[
|
||||
'index.md',
|
||||
'README.md',
|
||||
'foo.md',
|
||||
]
|
||||
)
|
||||
def test_get_files_exclude_readme_with_index(self, tdir):
|
||||
config = load_config(docs_dir=tdir)
|
||||
with self.assertLogs('mkdocs') as cm:
|
||||
files = get_files(config)
|
||||
self.assertRegex(
|
||||
'\n'.join(cm.output),
|
||||
r"^WARNING:mkdocs.structure.files:Both index.md and README.md found. Skipping README.md .+$",
|
||||
)
|
||||
expected = ['index.md', 'foo.md']
|
||||
self.assertIsInstance(files, Files)
|
||||
self.assertEqual(len(files), len(expected))
|
||||
self.assertEqual([f.src_path for f in files], expected)
|
||||
|
||||
@tempdir()
|
||||
@tempdir(files={'test.txt': 'source content'})
|
||||
def test_copy_file(self, src_dir, dest_dir):
|
||||
file = File('test.txt', src_dir, dest_dir, use_directory_urls=False)
|
||||
dest_path = os.path.join(dest_dir, 'test.txt')
|
||||
self.assertPathNotExists(dest_path)
|
||||
file.copy_file()
|
||||
self.assertPathIsFile(dest_path)
|
||||
|
||||
@tempdir(files={'test.txt': 'source content'})
|
||||
def test_copy_file_same_file(self, dest_dir):
|
||||
file = File('test.txt', dest_dir, dest_dir, use_directory_urls=False)
|
||||
dest_path = os.path.join(dest_dir, 'test.txt')
|
||||
file.copy_file()
|
||||
self.assertPathIsFile(dest_path)
|
||||
with open(dest_path, encoding='utf-8') as f:
|
||||
self.assertEqual(f.read(), 'source content')
|
||||
|
||||
@tempdir(files={'test.txt': 'destination content'})
|
||||
@tempdir(files={'test.txt': 'source content'})
|
||||
def test_copy_file_clean_modified(self, src_dir, dest_dir):
|
||||
file = File('test.txt', src_dir, dest_dir, use_directory_urls=False)
|
||||
file.is_modified = mock.Mock(return_value=True)
|
||||
dest_path = os.path.join(dest_dir, 'test.txt')
|
||||
file.copy_file(dirty=False)
|
||||
self.assertPathIsFile(dest_path)
|
||||
with open(dest_path, encoding='utf-8') as f:
|
||||
self.assertEqual(f.read(), 'source content')
|
||||
|
||||
@tempdir(files={'test.txt': 'destination content'})
|
||||
@tempdir(files={'test.txt': 'source content'})
|
||||
def test_copy_file_dirty_modified(self, src_dir, dest_dir):
|
||||
file = File('test.txt', src_dir, dest_dir, use_directory_urls=False)
|
||||
file.is_modified = mock.Mock(return_value=True)
|
||||
dest_path = os.path.join(dest_dir, 'test.txt')
|
||||
file.copy_file(dirty=True)
|
||||
self.assertPathIsFile(dest_path)
|
||||
with open(dest_path, encoding='utf-8') as f:
|
||||
self.assertEqual(f.read(), 'source content')
|
||||
|
||||
@tempdir(files={'test.txt': 'destination content'})
|
||||
@tempdir(files={'test.txt': 'source content'})
|
||||
def test_copy_file_dirty_not_modified(self, src_dir, dest_dir):
|
||||
file = File('test.txt', src_dir, dest_dir, use_directory_urls=False)
|
||||
file.is_modified = mock.Mock(return_value=False)
|
||||
dest_path = os.path.join(dest_dir, 'test.txt')
|
||||
file.copy_file(dirty=True)
|
||||
self.assertPathIsFile(dest_path)
|
||||
with open(dest_path, encoding='utf-8') as f:
|
||||
self.assertEqual(f.read(), 'destination content')
|
||||
|
||||
def test_files_append_remove_src_paths(self):
|
||||
fs = [
|
||||
File('index.md', '/path/to/docs', '/path/to/site', use_directory_urls=True),
|
||||
File('foo/bar.md', '/path/to/docs', '/path/to/site', use_directory_urls=True),
|
||||
File('foo/bar.html', '/path/to/docs', '/path/to/site', use_directory_urls=True),
|
||||
File('foo/bar.jpg', '/path/to/docs', '/path/to/site', use_directory_urls=True),
|
||||
File('foo/bar.js', '/path/to/docs', '/path/to/site', use_directory_urls=True),
|
||||
File('foo/bar.css', '/path/to/docs', '/path/to/site', use_directory_urls=True),
|
||||
]
|
||||
files = Files(fs)
|
||||
self.assertEqual(len(files), 6)
|
||||
self.assertEqual(len(files.src_uris), 6)
|
||||
extra_file = File('extra.md', '/path/to/docs', '/path/to/site', use_directory_urls=True)
|
||||
self.assertFalse(extra_file.src_uri in files.src_uris)
|
||||
files.append(extra_file)
|
||||
self.assertEqual(len(files), 7)
|
||||
self.assertEqual(len(files.src_uris), 7)
|
||||
self.assertTrue(extra_file.src_uri in files.src_uris)
|
||||
files.remove(extra_file)
|
||||
self.assertEqual(len(files), 6)
|
||||
self.assertEqual(len(files.src_uris), 6)
|
||||
self.assertFalse(extra_file.src_uri in files.src_uris)
|
||||
@ -0,0 +1,477 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from mkdocs.structure.files import File, Files
|
||||
from mkdocs.structure.nav import Section, _get_by_type, get_navigation
|
||||
from mkdocs.structure.pages import Page
|
||||
from mkdocs.tests.base import dedent, load_config
|
||||
|
||||
|
||||
class SiteNavigationTests(unittest.TestCase):
|
||||
maxDiff = None
|
||||
|
||||
def test_simple_nav(self):
|
||||
nav_cfg = [
|
||||
{'Home': 'index.md'},
|
||||
{'About': 'about.md'},
|
||||
]
|
||||
expected = dedent(
|
||||
"""
|
||||
Page(title='Home', url='/')
|
||||
Page(title='About', url='/about/')
|
||||
"""
|
||||
)
|
||||
cfg = load_config(nav=nav_cfg, site_url='http://example.com/')
|
||||
fs = [
|
||||
File(
|
||||
list(item.values())[0], cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls']
|
||||
)
|
||||
for item in nav_cfg
|
||||
]
|
||||
files = Files(fs)
|
||||
site_navigation = get_navigation(files, cfg)
|
||||
self.assertEqual(str(site_navigation).strip(), expected)
|
||||
self.assertEqual(len(site_navigation.items), 2)
|
||||
self.assertEqual(len(site_navigation.pages), 2)
|
||||
self.assertEqual(repr(site_navigation.homepage), "Page(title='Home', url='/')")
|
||||
|
||||
def test_nav_no_directory_urls(self):
|
||||
nav_cfg = [
|
||||
{'Home': 'index.md'},
|
||||
{'About': 'about.md'},
|
||||
]
|
||||
expected = dedent(
|
||||
"""
|
||||
Page(title='Home', url='/index.html')
|
||||
Page(title='About', url='/about.html')
|
||||
"""
|
||||
)
|
||||
cfg = load_config(nav=nav_cfg, use_directory_urls=False, site_url='http://example.com/')
|
||||
fs = [
|
||||
File(
|
||||
list(item.values())[0], cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls']
|
||||
)
|
||||
for item in nav_cfg
|
||||
]
|
||||
files = Files(fs)
|
||||
site_navigation = get_navigation(files, cfg)
|
||||
self.assertEqual(str(site_navigation).strip(), expected)
|
||||
self.assertEqual(len(site_navigation.items), 2)
|
||||
self.assertEqual(len(site_navigation.pages), 2)
|
||||
self.assertEqual(repr(site_navigation.homepage), "Page(title='Home', url='/index.html')")
|
||||
|
||||
def test_nav_missing_page(self):
|
||||
nav_cfg = [
|
||||
{'Home': 'index.md'},
|
||||
]
|
||||
expected = dedent(
|
||||
"""
|
||||
Page(title='Home', url='/')
|
||||
"""
|
||||
)
|
||||
cfg = load_config(nav=nav_cfg, site_url='http://example.com/')
|
||||
fs = [
|
||||
File('index.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls']),
|
||||
File('page_not_in_nav.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls']),
|
||||
]
|
||||
files = Files(fs)
|
||||
site_navigation = get_navigation(files, cfg)
|
||||
self.assertEqual(str(site_navigation).strip(), expected)
|
||||
self.assertEqual(len(site_navigation.items), 1)
|
||||
self.assertEqual(len(site_navigation.pages), 1)
|
||||
for file in files:
|
||||
self.assertIsInstance(file.page, Page)
|
||||
|
||||
def test_nav_no_title(self):
|
||||
nav_cfg = [
|
||||
'index.md',
|
||||
{'About': 'about.md'},
|
||||
]
|
||||
expected = dedent(
|
||||
"""
|
||||
Page(title=[blank], url='/')
|
||||
Page(title='About', url='/about/')
|
||||
"""
|
||||
)
|
||||
cfg = load_config(nav=nav_cfg, site_url='http://example.com/')
|
||||
fs = [
|
||||
File(nav_cfg[0], cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls']),
|
||||
File(nav_cfg[1]['About'], cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls']),
|
||||
]
|
||||
files = Files(fs)
|
||||
site_navigation = get_navigation(files, cfg)
|
||||
self.assertEqual(str(site_navigation).strip(), expected)
|
||||
self.assertEqual(len(site_navigation.items), 2)
|
||||
self.assertEqual(len(site_navigation.pages), 2)
|
||||
|
||||
def test_nav_external_links(self):
|
||||
nav_cfg = [
|
||||
{'Home': 'index.md'},
|
||||
{'Local': '/local.html'},
|
||||
{'External': 'http://example.com/external.html'},
|
||||
]
|
||||
expected = dedent(
|
||||
"""
|
||||
Page(title='Home', url='/')
|
||||
Link(title='Local', url='/local.html')
|
||||
Link(title='External', url='http://example.com/external.html')
|
||||
"""
|
||||
)
|
||||
cfg = load_config(nav=nav_cfg, site_url='http://example.com/')
|
||||
fs = [File('index.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls'])]
|
||||
files = Files(fs)
|
||||
with self.assertLogs('mkdocs', level='DEBUG') as cm:
|
||||
site_navigation = get_navigation(files, cfg)
|
||||
self.assertEqual(
|
||||
cm.output,
|
||||
[
|
||||
"DEBUG:mkdocs.structure.nav:An absolute path to '/local.html' is included in the "
|
||||
"'nav' configuration, which presumably points to an external resource.",
|
||||
"DEBUG:mkdocs.structure.nav:An external link to 'http://example.com/external.html' "
|
||||
"is included in the 'nav' configuration.",
|
||||
],
|
||||
)
|
||||
self.assertEqual(str(site_navigation).strip(), expected)
|
||||
self.assertEqual(len(site_navigation.items), 3)
|
||||
self.assertEqual(len(site_navigation.pages), 1)
|
||||
|
||||
def test_nav_bad_links(self):
|
||||
nav_cfg = [
|
||||
{'Home': 'index.md'},
|
||||
{'Missing': 'missing.html'},
|
||||
{'Bad External': 'example.com'},
|
||||
]
|
||||
expected = dedent(
|
||||
"""
|
||||
Page(title='Home', url='/')
|
||||
Link(title='Missing', url='missing.html')
|
||||
Link(title='Bad External', url='example.com')
|
||||
"""
|
||||
)
|
||||
cfg = load_config(nav=nav_cfg, site_url='http://example.com/')
|
||||
fs = [File('index.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls'])]
|
||||
files = Files(fs)
|
||||
with self.assertLogs('mkdocs') as cm:
|
||||
site_navigation = get_navigation(files, cfg)
|
||||
self.assertEqual(
|
||||
cm.output,
|
||||
[
|
||||
"WARNING:mkdocs.structure.nav:A relative path to 'missing.html' is included "
|
||||
"in the 'nav' configuration, which is not found in the documentation files",
|
||||
"WARNING:mkdocs.structure.nav:A relative path to 'example.com' is included "
|
||||
"in the 'nav' configuration, which is not found in the documentation files",
|
||||
],
|
||||
)
|
||||
self.assertEqual(str(site_navigation).strip(), expected)
|
||||
self.assertEqual(len(site_navigation.items), 3)
|
||||
self.assertEqual(len(site_navigation.pages), 1)
|
||||
|
||||
def test_indented_nav(self):
|
||||
nav_cfg = [
|
||||
{'Home': 'index.md'},
|
||||
{
|
||||
'API Guide': [
|
||||
{'Running': 'api-guide/running.md'},
|
||||
{'Testing': 'api-guide/testing.md'},
|
||||
{'Debugging': 'api-guide/debugging.md'},
|
||||
{
|
||||
'Advanced': [
|
||||
{'Part 1': 'api-guide/advanced/part-1.md'},
|
||||
]
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
'About': [
|
||||
{'Release notes': 'about/release-notes.md'},
|
||||
{'License': '/license.html'},
|
||||
]
|
||||
},
|
||||
{'External': 'https://example.com/'},
|
||||
]
|
||||
expected = dedent(
|
||||
"""
|
||||
Page(title='Home', url='/')
|
||||
Section(title='API Guide')
|
||||
Page(title='Running', url='/api-guide/running/')
|
||||
Page(title='Testing', url='/api-guide/testing/')
|
||||
Page(title='Debugging', url='/api-guide/debugging/')
|
||||
Section(title='Advanced')
|
||||
Page(title='Part 1', url='/api-guide/advanced/part-1/')
|
||||
Section(title='About')
|
||||
Page(title='Release notes', url='/about/release-notes/')
|
||||
Link(title='License', url='/license.html')
|
||||
Link(title='External', url='https://example.com/')
|
||||
"""
|
||||
)
|
||||
cfg = load_config(nav=nav_cfg, site_url='http://example.com/')
|
||||
fs = [
|
||||
'index.md',
|
||||
'api-guide/running.md',
|
||||
'api-guide/testing.md',
|
||||
'api-guide/debugging.md',
|
||||
'api-guide/advanced/part-1.md',
|
||||
'about/release-notes.md',
|
||||
]
|
||||
files = Files(
|
||||
[File(s, cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls']) for s in fs]
|
||||
)
|
||||
site_navigation = get_navigation(files, cfg)
|
||||
self.assertEqual(str(site_navigation).strip(), expected)
|
||||
self.assertEqual(len(site_navigation.items), 4)
|
||||
self.assertEqual(len(site_navigation.pages), 6)
|
||||
self.assertEqual(repr(site_navigation.homepage), "Page(title='Home', url='/')")
|
||||
self.assertIsNone(site_navigation.items[0].parent)
|
||||
self.assertEqual(site_navigation.items[0].ancestors, [])
|
||||
self.assertIsNone(site_navigation.items[1].parent)
|
||||
self.assertEqual(site_navigation.items[1].ancestors, [])
|
||||
self.assertEqual(len(site_navigation.items[1].children), 4)
|
||||
self.assertEqual(
|
||||
repr(site_navigation.items[1].children[0].parent), "Section(title='API Guide')"
|
||||
)
|
||||
self.assertEqual(site_navigation.items[1].children[0].ancestors, [site_navigation.items[1]])
|
||||
self.assertEqual(
|
||||
repr(site_navigation.items[1].children[1].parent), "Section(title='API Guide')"
|
||||
)
|
||||
self.assertEqual(site_navigation.items[1].children[1].ancestors, [site_navigation.items[1]])
|
||||
self.assertEqual(
|
||||
repr(site_navigation.items[1].children[2].parent), "Section(title='API Guide')"
|
||||
)
|
||||
self.assertEqual(site_navigation.items[1].children[2].ancestors, [site_navigation.items[1]])
|
||||
self.assertEqual(
|
||||
repr(site_navigation.items[1].children[3].parent), "Section(title='API Guide')"
|
||||
)
|
||||
self.assertEqual(site_navigation.items[1].children[3].ancestors, [site_navigation.items[1]])
|
||||
self.assertEqual(len(site_navigation.items[1].children[3].children), 1)
|
||||
self.assertEqual(
|
||||
repr(site_navigation.items[1].children[3].children[0].parent),
|
||||
"Section(title='Advanced')",
|
||||
)
|
||||
self.assertEqual(
|
||||
site_navigation.items[1].children[3].children[0].ancestors,
|
||||
[site_navigation.items[1].children[3], site_navigation.items[1]],
|
||||
)
|
||||
self.assertIsNone(site_navigation.items[2].parent)
|
||||
self.assertEqual(len(site_navigation.items[2].children), 2)
|
||||
self.assertEqual(
|
||||
repr(site_navigation.items[2].children[0].parent), "Section(title='About')"
|
||||
)
|
||||
self.assertEqual(site_navigation.items[2].children[0].ancestors, [site_navigation.items[2]])
|
||||
self.assertEqual(
|
||||
repr(site_navigation.items[2].children[1].parent), "Section(title='About')"
|
||||
)
|
||||
self.assertEqual(site_navigation.items[2].children[1].ancestors, [site_navigation.items[2]])
|
||||
self.assertIsNone(site_navigation.items[3].parent)
|
||||
self.assertEqual(site_navigation.items[3].ancestors, [])
|
||||
self.assertIsNone(site_navigation.items[3].children)
|
||||
|
||||
def test_nested_ungrouped_nav(self):
|
||||
nav_cfg = [
|
||||
{'Home': 'index.md'},
|
||||
{'Contact': 'about/contact.md'},
|
||||
{'License Title': 'about/sub/license.md'},
|
||||
]
|
||||
expected = dedent(
|
||||
"""
|
||||
Page(title='Home', url='/')
|
||||
Page(title='Contact', url='/about/contact/')
|
||||
Page(title='License Title', url='/about/sub/license/')
|
||||
"""
|
||||
)
|
||||
cfg = load_config(nav=nav_cfg, site_url='http://example.com/')
|
||||
fs = [
|
||||
File(
|
||||
list(item.values())[0], cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls']
|
||||
)
|
||||
for item in nav_cfg
|
||||
]
|
||||
files = Files(fs)
|
||||
site_navigation = get_navigation(files, cfg)
|
||||
self.assertEqual(str(site_navigation).strip(), expected)
|
||||
self.assertEqual(len(site_navigation.items), 3)
|
||||
self.assertEqual(len(site_navigation.pages), 3)
|
||||
|
||||
def test_nested_ungrouped_nav_no_titles(self):
|
||||
nav_cfg = [
|
||||
'index.md',
|
||||
'about/contact.md',
|
||||
'about/sub/license.md',
|
||||
]
|
||||
expected = dedent(
|
||||
"""
|
||||
Page(title=[blank], url='/')
|
||||
Page(title=[blank], url='/about/contact/')
|
||||
Page(title=[blank], url='/about/sub/license/')
|
||||
"""
|
||||
)
|
||||
|
||||
cfg = load_config(nav=nav_cfg, site_url='http://example.com/')
|
||||
fs = [
|
||||
File(item, cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls'])
|
||||
for item in nav_cfg
|
||||
]
|
||||
files = Files(fs)
|
||||
site_navigation = get_navigation(files, cfg)
|
||||
self.assertEqual(str(site_navigation).strip(), expected)
|
||||
self.assertEqual(len(site_navigation.items), 3)
|
||||
self.assertEqual(len(site_navigation.pages), 3)
|
||||
self.assertEqual(repr(site_navigation.homepage), "Page(title=[blank], url='/')")
|
||||
|
||||
@unittest.skipUnless(sys.platform.startswith("win"), "requires Windows")
|
||||
def test_nested_ungrouped_no_titles_windows(self):
|
||||
nav_cfg = [
|
||||
'index.md',
|
||||
'about\\contact.md',
|
||||
'about\\sub\\license.md',
|
||||
]
|
||||
expected = dedent(
|
||||
"""
|
||||
Page(title=[blank], url='/')
|
||||
Page(title=[blank], url='/about/contact/')
|
||||
Page(title=[blank], url='/about/sub/license/')
|
||||
"""
|
||||
)
|
||||
|
||||
cfg = load_config(nav=nav_cfg, site_url='http://example.com/')
|
||||
fs = [
|
||||
File(item, cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls'])
|
||||
for item in nav_cfg
|
||||
]
|
||||
files = Files(fs)
|
||||
site_navigation = get_navigation(files, cfg)
|
||||
self.assertEqual(str(site_navigation).strip(), expected)
|
||||
self.assertEqual(len(site_navigation.items), 3)
|
||||
self.assertEqual(len(site_navigation.pages), 3)
|
||||
|
||||
def test_nav_from_files(self):
|
||||
expected = dedent(
|
||||
"""
|
||||
Page(title=[blank], url='/')
|
||||
Page(title=[blank], url='/about/')
|
||||
"""
|
||||
)
|
||||
cfg = load_config(site_url='http://example.com/')
|
||||
fs = [
|
||||
File('index.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls']),
|
||||
File('about.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls']),
|
||||
]
|
||||
files = Files(fs)
|
||||
site_navigation = get_navigation(files, cfg)
|
||||
self.assertEqual(str(site_navigation).strip(), expected)
|
||||
self.assertEqual(len(site_navigation.items), 2)
|
||||
self.assertEqual(len(site_navigation.pages), 2)
|
||||
self.assertEqual(repr(site_navigation.homepage), "Page(title=[blank], url='/')")
|
||||
|
||||
def test_nav_from_nested_files(self):
|
||||
expected = dedent(
|
||||
"""
|
||||
Page(title=[blank], url='/')
|
||||
Section(title='About')
|
||||
Page(title=[blank], url='/about/license/')
|
||||
Page(title=[blank], url='/about/release-notes/')
|
||||
Section(title='Api guide')
|
||||
Page(title=[blank], url='/api-guide/debugging/')
|
||||
Page(title=[blank], url='/api-guide/running/')
|
||||
Page(title=[blank], url='/api-guide/testing/')
|
||||
Section(title='Advanced')
|
||||
Page(title=[blank], url='/api-guide/advanced/part-1/')
|
||||
"""
|
||||
)
|
||||
cfg = load_config(site_url='http://example.com/')
|
||||
fs = [
|
||||
'index.md',
|
||||
'about/license.md',
|
||||
'about/release-notes.md',
|
||||
'api-guide/debugging.md',
|
||||
'api-guide/running.md',
|
||||
'api-guide/testing.md',
|
||||
'api-guide/advanced/part-1.md',
|
||||
]
|
||||
files = Files(
|
||||
[File(s, cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls']) for s in fs]
|
||||
)
|
||||
site_navigation = get_navigation(files, cfg)
|
||||
self.assertEqual(str(site_navigation).strip(), expected)
|
||||
self.assertEqual(len(site_navigation.items), 3)
|
||||
self.assertEqual(len(site_navigation.pages), 7)
|
||||
self.assertEqual(repr(site_navigation.homepage), "Page(title=[blank], url='/')")
|
||||
|
||||
def test_active(self):
|
||||
nav_cfg = [
|
||||
{'Home': 'index.md'},
|
||||
{
|
||||
'API Guide': [
|
||||
{'Running': 'api-guide/running.md'},
|
||||
{'Testing': 'api-guide/testing.md'},
|
||||
{'Debugging': 'api-guide/debugging.md'},
|
||||
{
|
||||
'Advanced': [
|
||||
{'Part 1': 'api-guide/advanced/part-1.md'},
|
||||
]
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
'About': [
|
||||
{'Release notes': 'about/release-notes.md'},
|
||||
{'License': 'about/license.md'},
|
||||
]
|
||||
},
|
||||
]
|
||||
cfg = load_config(nav=nav_cfg, site_url='http://example.com/')
|
||||
fs = [
|
||||
'index.md',
|
||||
'api-guide/running.md',
|
||||
'api-guide/testing.md',
|
||||
'api-guide/debugging.md',
|
||||
'api-guide/advanced/part-1.md',
|
||||
'about/release-notes.md',
|
||||
'about/license.md',
|
||||
]
|
||||
files = Files(
|
||||
[File(s, cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls']) for s in fs]
|
||||
)
|
||||
site_navigation = get_navigation(files, cfg)
|
||||
# Confirm nothing is active
|
||||
self.assertTrue(all(page.active is False for page in site_navigation.pages))
|
||||
self.assertTrue(all(item.active is False for item in site_navigation.items))
|
||||
# Activate
|
||||
site_navigation.items[1].children[3].children[0].active = True
|
||||
# Confirm ancestors are activated
|
||||
self.assertTrue(site_navigation.items[1].children[3].children[0].active)
|
||||
self.assertTrue(site_navigation.items[1].children[3].active)
|
||||
self.assertTrue(site_navigation.items[1].active)
|
||||
# Confirm non-ancestors are not activated
|
||||
self.assertFalse(site_navigation.items[0].active)
|
||||
self.assertFalse(site_navigation.items[1].children[0].active)
|
||||
self.assertFalse(site_navigation.items[1].children[1].active)
|
||||
self.assertFalse(site_navigation.items[1].children[2].active)
|
||||
self.assertFalse(site_navigation.items[2].active)
|
||||
self.assertFalse(site_navigation.items[2].children[0].active)
|
||||
self.assertFalse(site_navigation.items[2].children[1].active)
|
||||
# Deactivate
|
||||
site_navigation.items[1].children[3].children[0].active = False
|
||||
# Confirm ancestors are deactivated
|
||||
self.assertFalse(site_navigation.items[1].children[3].children[0].active)
|
||||
self.assertFalse(site_navigation.items[1].children[3].active)
|
||||
self.assertFalse(site_navigation.items[1].active)
|
||||
|
||||
def test_get_by_type_nested_sections(self):
|
||||
nav_cfg = [
|
||||
{
|
||||
'Section 1': [
|
||||
{
|
||||
'Section 2': [
|
||||
{'Page': 'page.md'},
|
||||
]
|
||||
},
|
||||
]
|
||||
},
|
||||
]
|
||||
cfg = load_config(nav=nav_cfg, site_url='http://example.com/')
|
||||
fs = [File('page.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls'])]
|
||||
files = Files(fs)
|
||||
site_navigation = get_navigation(files, cfg)
|
||||
self.assertEqual(len(_get_by_type(site_navigation, Section)), 2)
|
||||
@ -0,0 +1,815 @@
|
||||
import functools
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
from unittest import mock
|
||||
|
||||
from mkdocs.structure.files import File, Files
|
||||
from mkdocs.structure.pages import Page
|
||||
from mkdocs.tests.base import dedent, load_config, tempdir
|
||||
|
||||
load_config = functools.lru_cache(maxsize=None)(load_config)
|
||||
|
||||
|
||||
class PageTests(unittest.TestCase):
|
||||
DOCS_DIR = os.path.join(
|
||||
os.path.abspath(os.path.dirname(__file__)), '../integration/subpages/docs'
|
||||
)
|
||||
|
||||
def test_homepage(self):
|
||||
cfg = load_config(docs_dir=self.DOCS_DIR)
|
||||
fl = File('index.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls'])
|
||||
self.assertIsNone(fl.page)
|
||||
pg = Page('Foo', fl, cfg)
|
||||
self.assertEqual(fl.page, pg)
|
||||
self.assertEqual(pg.url, '')
|
||||
self.assertEqual(pg.abs_url, None)
|
||||
self.assertEqual(pg.canonical_url, None)
|
||||
self.assertEqual(pg.edit_url, None)
|
||||
self.assertEqual(pg.file, fl)
|
||||
self.assertEqual(pg.content, None)
|
||||
self.assertTrue(pg.is_homepage)
|
||||
self.assertTrue(pg.is_index)
|
||||
self.assertTrue(pg.is_page)
|
||||
self.assertFalse(pg.is_section)
|
||||
self.assertTrue(pg.is_top_level)
|
||||
self.assertEqual(pg.markdown, None)
|
||||
self.assertEqual(pg.meta, {})
|
||||
self.assertEqual(pg.next_page, None)
|
||||
self.assertEqual(pg.parent, None)
|
||||
self.assertEqual(pg.previous_page, None)
|
||||
self.assertEqual(pg.title, 'Foo')
|
||||
self.assertEqual(pg.toc, [])
|
||||
|
||||
def test_nested_index_page(self):
|
||||
cfg = load_config(docs_dir=self.DOCS_DIR)
|
||||
fl = File('sub1/index.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls'])
|
||||
pg = Page('Foo', fl, cfg)
|
||||
pg.parent = 'foo'
|
||||
self.assertEqual(pg.url, 'sub1/')
|
||||
self.assertEqual(pg.abs_url, None)
|
||||
self.assertEqual(pg.canonical_url, None)
|
||||
self.assertEqual(pg.edit_url, None)
|
||||
self.assertEqual(pg.file, fl)
|
||||
self.assertEqual(pg.content, None)
|
||||
self.assertFalse(pg.is_homepage)
|
||||
self.assertTrue(pg.is_index)
|
||||
self.assertTrue(pg.is_page)
|
||||
self.assertFalse(pg.is_section)
|
||||
self.assertFalse(pg.is_top_level)
|
||||
self.assertEqual(pg.markdown, None)
|
||||
self.assertEqual(pg.meta, {})
|
||||
self.assertEqual(pg.next_page, None)
|
||||
self.assertEqual(pg.parent, 'foo')
|
||||
self.assertEqual(pg.previous_page, None)
|
||||
self.assertEqual(pg.title, 'Foo')
|
||||
self.assertEqual(pg.toc, [])
|
||||
|
||||
def test_nested_index_page_no_parent(self):
|
||||
cfg = load_config(docs_dir=self.DOCS_DIR)
|
||||
fl = File('sub1/index.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls'])
|
||||
pg = Page('Foo', fl, cfg)
|
||||
pg.parent = None # non-homepage at nav root level; see #1919.
|
||||
self.assertEqual(pg.url, 'sub1/')
|
||||
self.assertEqual(pg.abs_url, None)
|
||||
self.assertEqual(pg.canonical_url, None)
|
||||
self.assertEqual(pg.edit_url, None)
|
||||
self.assertEqual(pg.file, fl)
|
||||
self.assertEqual(pg.content, None)
|
||||
self.assertFalse(pg.is_homepage)
|
||||
self.assertTrue(pg.is_index)
|
||||
self.assertTrue(pg.is_page)
|
||||
self.assertFalse(pg.is_section)
|
||||
self.assertTrue(pg.is_top_level)
|
||||
self.assertEqual(pg.markdown, None)
|
||||
self.assertEqual(pg.meta, {})
|
||||
self.assertEqual(pg.next_page, None)
|
||||
self.assertEqual(pg.parent, None)
|
||||
self.assertEqual(pg.previous_page, None)
|
||||
self.assertEqual(pg.title, 'Foo')
|
||||
self.assertEqual(pg.toc, [])
|
||||
|
||||
def test_nested_index_page_no_parent_no_directory_urls(self):
|
||||
cfg = load_config(docs_dir=self.DOCS_DIR, use_directory_urls=False)
|
||||
fl = File('sub1/index.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls'])
|
||||
pg = Page('Foo', fl, cfg)
|
||||
pg.parent = None # non-homepage at nav root level; see #1919.
|
||||
self.assertEqual(pg.url, 'sub1/index.html')
|
||||
self.assertEqual(pg.abs_url, None)
|
||||
self.assertEqual(pg.canonical_url, None)
|
||||
self.assertEqual(pg.edit_url, None)
|
||||
self.assertEqual(pg.file, fl)
|
||||
self.assertEqual(pg.content, None)
|
||||
self.assertFalse(pg.is_homepage)
|
||||
self.assertTrue(pg.is_index)
|
||||
self.assertTrue(pg.is_page)
|
||||
self.assertFalse(pg.is_section)
|
||||
self.assertTrue(pg.is_top_level)
|
||||
self.assertEqual(pg.markdown, None)
|
||||
self.assertEqual(pg.meta, {})
|
||||
self.assertEqual(pg.next_page, None)
|
||||
self.assertEqual(pg.parent, None)
|
||||
self.assertEqual(pg.previous_page, None)
|
||||
self.assertEqual(pg.title, 'Foo')
|
||||
self.assertEqual(pg.toc, [])
|
||||
|
||||
def test_nested_nonindex_page(self):
|
||||
cfg = load_config(docs_dir=self.DOCS_DIR)
|
||||
fl = File('sub1/non-index.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls'])
|
||||
pg = Page('Foo', fl, cfg)
|
||||
pg.parent = 'foo'
|
||||
self.assertEqual(pg.url, 'sub1/non-index/')
|
||||
self.assertEqual(pg.abs_url, None)
|
||||
self.assertEqual(pg.canonical_url, None)
|
||||
self.assertEqual(pg.edit_url, None)
|
||||
self.assertEqual(pg.file, fl)
|
||||
self.assertEqual(pg.content, None)
|
||||
self.assertFalse(pg.is_homepage)
|
||||
self.assertFalse(pg.is_index)
|
||||
self.assertTrue(pg.is_page)
|
||||
self.assertFalse(pg.is_section)
|
||||
self.assertFalse(pg.is_top_level)
|
||||
self.assertEqual(pg.markdown, None)
|
||||
self.assertEqual(pg.meta, {})
|
||||
self.assertEqual(pg.next_page, None)
|
||||
self.assertEqual(pg.parent, 'foo')
|
||||
self.assertEqual(pg.previous_page, None)
|
||||
self.assertEqual(pg.title, 'Foo')
|
||||
self.assertEqual(pg.toc, [])
|
||||
|
||||
def test_page_defaults(self):
|
||||
cfg = load_config()
|
||||
fl = File('testing.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls'])
|
||||
pg = Page('Foo', fl, cfg)
|
||||
self.assertRegex(pg.update_date, r'\d{4}-\d{2}-\d{2}')
|
||||
self.assertEqual(pg.url, 'testing/')
|
||||
self.assertEqual(pg.abs_url, None)
|
||||
self.assertEqual(pg.canonical_url, None)
|
||||
self.assertEqual(pg.edit_url, None)
|
||||
self.assertEqual(pg.file, fl)
|
||||
self.assertEqual(pg.content, None)
|
||||
self.assertFalse(pg.is_homepage)
|
||||
self.assertFalse(pg.is_index)
|
||||
self.assertTrue(pg.is_page)
|
||||
self.assertFalse(pg.is_section)
|
||||
self.assertTrue(pg.is_top_level)
|
||||
self.assertEqual(pg.markdown, None)
|
||||
self.assertEqual(pg.meta, {})
|
||||
self.assertEqual(pg.next_page, None)
|
||||
self.assertEqual(pg.parent, None)
|
||||
self.assertEqual(pg.previous_page, None)
|
||||
self.assertEqual(pg.title, 'Foo')
|
||||
self.assertEqual(pg.toc, [])
|
||||
|
||||
def test_page_no_directory_url(self):
|
||||
cfg = load_config(use_directory_urls=False)
|
||||
fl = File('testing.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls'])
|
||||
pg = Page('Foo', fl, cfg)
|
||||
self.assertEqual(pg.url, 'testing.html')
|
||||
self.assertEqual(pg.abs_url, None)
|
||||
self.assertEqual(pg.canonical_url, None)
|
||||
self.assertEqual(pg.edit_url, None)
|
||||
self.assertEqual(pg.file, fl)
|
||||
self.assertEqual(pg.content, None)
|
||||
self.assertFalse(pg.is_homepage)
|
||||
self.assertFalse(pg.is_index)
|
||||
self.assertTrue(pg.is_page)
|
||||
self.assertFalse(pg.is_section)
|
||||
self.assertTrue(pg.is_top_level)
|
||||
self.assertEqual(pg.markdown, None)
|
||||
self.assertEqual(pg.meta, {})
|
||||
self.assertEqual(pg.next_page, None)
|
||||
self.assertEqual(pg.parent, None)
|
||||
self.assertEqual(pg.previous_page, None)
|
||||
self.assertEqual(pg.title, 'Foo')
|
||||
self.assertEqual(pg.toc, [])
|
||||
|
||||
def test_page_canonical_url(self):
|
||||
cfg = load_config(site_url='http://example.com')
|
||||
fl = File('testing.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls'])
|
||||
pg = Page('Foo', fl, cfg)
|
||||
self.assertEqual(pg.url, 'testing/')
|
||||
self.assertEqual(pg.abs_url, '/testing/')
|
||||
self.assertEqual(pg.canonical_url, 'http://example.com/testing/')
|
||||
self.assertEqual(pg.edit_url, None)
|
||||
self.assertEqual(pg.file, fl)
|
||||
self.assertEqual(pg.content, None)
|
||||
self.assertFalse(pg.is_homepage)
|
||||
self.assertFalse(pg.is_index)
|
||||
self.assertTrue(pg.is_page)
|
||||
self.assertFalse(pg.is_section)
|
||||
self.assertTrue(pg.is_top_level)
|
||||
self.assertEqual(pg.markdown, None)
|
||||
self.assertEqual(pg.meta, {})
|
||||
self.assertEqual(pg.next_page, None)
|
||||
self.assertEqual(pg.parent, None)
|
||||
self.assertEqual(pg.previous_page, None)
|
||||
self.assertEqual(pg.title, 'Foo')
|
||||
self.assertEqual(pg.toc, [])
|
||||
|
||||
def test_page_canonical_url_nested(self):
|
||||
cfg = load_config(site_url='http://example.com/foo/')
|
||||
fl = File('testing.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls'])
|
||||
pg = Page('Foo', fl, cfg)
|
||||
self.assertEqual(pg.url, 'testing/')
|
||||
self.assertEqual(pg.abs_url, '/foo/testing/')
|
||||
self.assertEqual(pg.canonical_url, 'http://example.com/foo/testing/')
|
||||
self.assertEqual(pg.edit_url, None)
|
||||
self.assertEqual(pg.file, fl)
|
||||
self.assertEqual(pg.content, None)
|
||||
self.assertFalse(pg.is_homepage)
|
||||
self.assertFalse(pg.is_index)
|
||||
self.assertTrue(pg.is_page)
|
||||
self.assertFalse(pg.is_section)
|
||||
self.assertTrue(pg.is_top_level)
|
||||
self.assertEqual(pg.markdown, None)
|
||||
self.assertEqual(pg.meta, {})
|
||||
self.assertEqual(pg.next_page, None)
|
||||
self.assertEqual(pg.parent, None)
|
||||
self.assertEqual(pg.previous_page, None)
|
||||
self.assertEqual(pg.title, 'Foo')
|
||||
self.assertEqual(pg.toc, [])
|
||||
|
||||
def test_page_canonical_url_nested_no_slash(self):
|
||||
cfg = load_config(site_url='http://example.com/foo')
|
||||
fl = File('testing.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls'])
|
||||
pg = Page('Foo', fl, cfg)
|
||||
self.assertEqual(pg.url, 'testing/')
|
||||
self.assertEqual(pg.abs_url, '/foo/testing/')
|
||||
self.assertEqual(pg.canonical_url, 'http://example.com/foo/testing/')
|
||||
self.assertEqual(pg.edit_url, None)
|
||||
self.assertEqual(pg.file, fl)
|
||||
self.assertEqual(pg.content, None)
|
||||
self.assertFalse(pg.is_homepage)
|
||||
self.assertFalse(pg.is_index)
|
||||
self.assertTrue(pg.is_page)
|
||||
self.assertFalse(pg.is_section)
|
||||
self.assertTrue(pg.is_top_level)
|
||||
self.assertEqual(pg.markdown, None)
|
||||
self.assertEqual(pg.meta, {})
|
||||
self.assertEqual(pg.next_page, None)
|
||||
self.assertEqual(pg.parent, None)
|
||||
self.assertEqual(pg.previous_page, None)
|
||||
self.assertEqual(pg.title, 'Foo')
|
||||
self.assertEqual(pg.toc, [])
|
||||
|
||||
def test_predefined_page_title(self):
|
||||
cfg = load_config()
|
||||
fl = File('testing.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls'])
|
||||
pg = Page('Page Title', fl, cfg)
|
||||
pg.read_source(cfg)
|
||||
self.assertEqual(pg.url, 'testing/')
|
||||
self.assertEqual(pg.abs_url, None)
|
||||
self.assertEqual(pg.canonical_url, None)
|
||||
self.assertEqual(pg.edit_url, None)
|
||||
self.assertEqual(pg.file, fl)
|
||||
self.assertEqual(pg.content, None)
|
||||
self.assertFalse(pg.is_homepage)
|
||||
self.assertFalse(pg.is_index)
|
||||
self.assertTrue(pg.is_page)
|
||||
self.assertFalse(pg.is_section)
|
||||
self.assertTrue(pg.is_top_level)
|
||||
self.assertTrue(pg.markdown.startswith('# Welcome to MkDocs\n'))
|
||||
self.assertEqual(pg.meta, {})
|
||||
self.assertEqual(pg.next_page, None)
|
||||
self.assertEqual(pg.parent, None)
|
||||
self.assertEqual(pg.previous_page, None)
|
||||
self.assertEqual(pg.title, 'Page Title')
|
||||
self.assertEqual(pg.toc, [])
|
||||
|
||||
def test_page_title_from_markdown(self):
|
||||
cfg = load_config()
|
||||
fl = File('testing.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls'])
|
||||
pg = Page(None, fl, cfg)
|
||||
pg.read_source(cfg)
|
||||
self.assertEqual(pg.url, 'testing/')
|
||||
self.assertEqual(pg.abs_url, None)
|
||||
self.assertEqual(pg.canonical_url, None)
|
||||
self.assertEqual(pg.edit_url, None)
|
||||
self.assertEqual(pg.file, fl)
|
||||
self.assertEqual(pg.content, None)
|
||||
self.assertFalse(pg.is_homepage)
|
||||
self.assertFalse(pg.is_index)
|
||||
self.assertTrue(pg.is_page)
|
||||
self.assertFalse(pg.is_section)
|
||||
self.assertTrue(pg.is_top_level)
|
||||
self.assertTrue(pg.markdown.startswith('# Welcome to MkDocs\n'))
|
||||
self.assertEqual(pg.meta, {})
|
||||
self.assertEqual(pg.next_page, None)
|
||||
self.assertEqual(pg.parent, None)
|
||||
self.assertEqual(pg.previous_page, None)
|
||||
self.assertEqual(pg.title, 'Welcome to MkDocs')
|
||||
self.assertEqual(pg.toc, [])
|
||||
|
||||
def test_page_title_from_meta(self):
|
||||
cfg = load_config(docs_dir=self.DOCS_DIR)
|
||||
fl = File('metadata.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls'])
|
||||
pg = Page(None, fl, cfg)
|
||||
pg.read_source(cfg)
|
||||
self.assertEqual(pg.url, 'metadata/')
|
||||
self.assertEqual(pg.abs_url, None)
|
||||
self.assertEqual(pg.canonical_url, None)
|
||||
self.assertEqual(pg.edit_url, None)
|
||||
self.assertEqual(pg.file, fl)
|
||||
self.assertEqual(pg.content, None)
|
||||
self.assertFalse(pg.is_homepage)
|
||||
self.assertFalse(pg.is_index)
|
||||
self.assertTrue(pg.is_page)
|
||||
self.assertFalse(pg.is_section)
|
||||
self.assertTrue(pg.is_top_level)
|
||||
self.assertTrue(pg.markdown.startswith('# Welcome to MkDocs\n'))
|
||||
self.assertEqual(pg.meta, {'title': 'A Page Title'})
|
||||
self.assertEqual(pg.next_page, None)
|
||||
self.assertEqual(pg.parent, None)
|
||||
self.assertEqual(pg.previous_page, None)
|
||||
self.assertEqual(pg.title, 'A Page Title')
|
||||
self.assertEqual(pg.toc, [])
|
||||
|
||||
def test_page_title_from_filename(self):
|
||||
cfg = load_config(docs_dir=self.DOCS_DIR)
|
||||
fl = File('page-title.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls'])
|
||||
pg = Page(None, fl, cfg)
|
||||
pg.read_source(cfg)
|
||||
self.assertEqual(pg.url, 'page-title/')
|
||||
self.assertEqual(pg.abs_url, None)
|
||||
self.assertEqual(pg.canonical_url, None)
|
||||
self.assertEqual(pg.edit_url, None)
|
||||
self.assertEqual(pg.file, fl)
|
||||
self.assertEqual(pg.content, None)
|
||||
self.assertFalse(pg.is_homepage)
|
||||
self.assertFalse(pg.is_index)
|
||||
self.assertTrue(pg.is_page)
|
||||
self.assertFalse(pg.is_section)
|
||||
self.assertTrue(pg.is_top_level)
|
||||
self.assertTrue(pg.markdown.startswith('Page content.\n'))
|
||||
self.assertEqual(pg.meta, {})
|
||||
self.assertEqual(pg.next_page, None)
|
||||
self.assertEqual(pg.parent, None)
|
||||
self.assertEqual(pg.previous_page, None)
|
||||
self.assertEqual(pg.title, 'Page title')
|
||||
self.assertEqual(pg.toc, [])
|
||||
|
||||
def test_page_title_from_capitalized_filename(self):
|
||||
cfg = load_config(docs_dir=self.DOCS_DIR)
|
||||
fl = File('pageTitle.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls'])
|
||||
pg = Page(None, fl, cfg)
|
||||
pg.read_source(cfg)
|
||||
self.assertEqual(pg.url, 'pageTitle/')
|
||||
self.assertEqual(pg.abs_url, None)
|
||||
self.assertEqual(pg.canonical_url, None)
|
||||
self.assertEqual(pg.edit_url, None)
|
||||
self.assertEqual(pg.file, fl)
|
||||
self.assertEqual(pg.content, None)
|
||||
self.assertFalse(pg.is_homepage)
|
||||
self.assertFalse(pg.is_index)
|
||||
self.assertTrue(pg.is_page)
|
||||
self.assertFalse(pg.is_section)
|
||||
self.assertTrue(pg.is_top_level)
|
||||
self.assertTrue(pg.markdown.startswith('Page content.\n'))
|
||||
self.assertEqual(pg.meta, {})
|
||||
self.assertEqual(pg.next_page, None)
|
||||
self.assertEqual(pg.parent, None)
|
||||
self.assertEqual(pg.previous_page, None)
|
||||
self.assertEqual(pg.title, 'pageTitle')
|
||||
self.assertEqual(pg.toc, [])
|
||||
|
||||
def test_page_title_from_homepage_filename(self):
|
||||
cfg = load_config(docs_dir=self.DOCS_DIR)
|
||||
fl = File('index.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls'])
|
||||
pg = Page(None, fl, cfg)
|
||||
pg.read_source(cfg)
|
||||
self.assertEqual(pg.url, '')
|
||||
self.assertEqual(pg.abs_url, None)
|
||||
self.assertEqual(pg.canonical_url, None)
|
||||
self.assertEqual(pg.edit_url, None)
|
||||
self.assertEqual(pg.file, fl)
|
||||
self.assertEqual(pg.content, None)
|
||||
self.assertTrue(pg.is_homepage)
|
||||
self.assertTrue(pg.is_index)
|
||||
self.assertTrue(pg.is_page)
|
||||
self.assertFalse(pg.is_section)
|
||||
self.assertTrue(pg.is_top_level)
|
||||
self.assertTrue(pg.markdown.startswith('## Test'))
|
||||
self.assertEqual(pg.meta, {})
|
||||
self.assertEqual(pg.next_page, None)
|
||||
self.assertEqual(pg.parent, None)
|
||||
self.assertEqual(pg.previous_page, None)
|
||||
self.assertEqual(pg.title, 'Home')
|
||||
self.assertEqual(pg.toc, [])
|
||||
|
||||
def test_page_eq(self):
|
||||
cfg = load_config()
|
||||
fl = File('testing.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls'])
|
||||
pg = Page('Foo', fl, cfg)
|
||||
self.assertTrue(pg == Page('Foo', fl, cfg))
|
||||
|
||||
def test_page_ne(self):
|
||||
cfg = load_config()
|
||||
f1 = File('testing.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls'])
|
||||
f2 = File('index.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls'])
|
||||
pg = Page('Foo', f1, cfg)
|
||||
# Different Title
|
||||
self.assertTrue(pg != Page('Bar', f1, cfg))
|
||||
# Different File
|
||||
self.assertTrue(pg != Page('Foo', f2, cfg))
|
||||
|
||||
@tempdir()
|
||||
def test_BOM(self, docs_dir):
|
||||
md_src = '# An UTF-8 encoded file with a BOM'
|
||||
cfg = load_config(docs_dir=docs_dir)
|
||||
fl = File('index.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls'])
|
||||
pg = Page(None, fl, cfg)
|
||||
# Create an UTF-8 Encoded file with BOM (as Microsoft editors do). See #1186
|
||||
with open(fl.abs_src_path, 'w', encoding='utf-8-sig') as f:
|
||||
f.write(md_src)
|
||||
# Now read the file.
|
||||
pg.read_source(cfg)
|
||||
# Ensure the BOM (`\ufeff`) is removed
|
||||
self.assertNotIn('\ufeff', pg.markdown)
|
||||
self.assertEqual(pg.markdown, md_src)
|
||||
self.assertEqual(pg.meta, {})
|
||||
|
||||
def test_page_edit_url(
|
||||
self, paths={'testing.md': 'testing/', 'sub1/non-index.md': 'sub1/non-index/'}
|
||||
):
|
||||
for case in [
|
||||
dict(
|
||||
config={'repo_url': 'http://github.com/mkdocs/mkdocs'},
|
||||
edit_url='http://github.com/mkdocs/mkdocs/edit/master/docs/testing.md',
|
||||
edit_url2='http://github.com/mkdocs/mkdocs/edit/master/docs/sub1/non-index.md',
|
||||
),
|
||||
dict(
|
||||
config={'repo_url': 'https://github.com/mkdocs/mkdocs/'},
|
||||
edit_url='https://github.com/mkdocs/mkdocs/edit/master/docs/testing.md',
|
||||
edit_url2='https://github.com/mkdocs/mkdocs/edit/master/docs/sub1/non-index.md',
|
||||
),
|
||||
dict(
|
||||
config={'repo_url': 'http://example.com'},
|
||||
edit_url=None,
|
||||
edit_url2=None,
|
||||
),
|
||||
dict(
|
||||
config={'repo_url': 'http://example.com', 'edit_uri': 'edit/master'},
|
||||
edit_url='http://example.com/edit/master/testing.md',
|
||||
edit_url2='http://example.com/edit/master/sub1/non-index.md',
|
||||
),
|
||||
dict(
|
||||
config={'repo_url': 'http://example.com', 'edit_uri': '/edit/master'},
|
||||
edit_url='http://example.com/edit/master/testing.md',
|
||||
edit_url2='http://example.com/edit/master/sub1/non-index.md',
|
||||
),
|
||||
dict(
|
||||
config={'repo_url': 'http://example.com/foo/', 'edit_uri': '/edit/master/'},
|
||||
edit_url='http://example.com/edit/master/testing.md',
|
||||
edit_url2='http://example.com/edit/master/sub1/non-index.md',
|
||||
),
|
||||
dict(
|
||||
config={'repo_url': 'http://example.com/foo', 'edit_uri': '/edit/master/'},
|
||||
edit_url='http://example.com/edit/master/testing.md',
|
||||
edit_url2='http://example.com/edit/master/sub1/non-index.md',
|
||||
),
|
||||
dict(
|
||||
config={'repo_url': 'http://example.com/foo/', 'edit_uri': '/edit/master'},
|
||||
edit_url='http://example.com/edit/master/testing.md',
|
||||
edit_url2='http://example.com/edit/master/sub1/non-index.md',
|
||||
),
|
||||
dict(
|
||||
config={'repo_url': 'http://example.com/foo/', 'edit_uri': 'edit/master/'},
|
||||
edit_url='http://example.com/foo/edit/master/testing.md',
|
||||
edit_url2='http://example.com/foo/edit/master/sub1/non-index.md',
|
||||
),
|
||||
dict(
|
||||
config={'repo_url': 'http://example.com/foo', 'edit_uri': 'edit/master/'},
|
||||
edit_url='http://example.com/foo/edit/master/testing.md',
|
||||
edit_url2='http://example.com/foo/edit/master/sub1/non-index.md',
|
||||
),
|
||||
dict(
|
||||
config={'repo_url': 'http://example.com', 'edit_uri': '?query=edit/master'},
|
||||
edit_url='http://example.com?query=edit/master/testing.md',
|
||||
edit_url2='http://example.com?query=edit/master/sub1/non-index.md',
|
||||
),
|
||||
dict(
|
||||
config={'repo_url': 'http://example.com/', 'edit_uri': '?query=edit/master/'},
|
||||
edit_url='http://example.com/?query=edit/master/testing.md',
|
||||
edit_url2='http://example.com/?query=edit/master/sub1/non-index.md',
|
||||
),
|
||||
dict(
|
||||
config={'repo_url': 'http://example.com', 'edit_uri': '#edit/master'},
|
||||
edit_url='http://example.com#edit/master/testing.md',
|
||||
edit_url2='http://example.com#edit/master/sub1/non-index.md',
|
||||
),
|
||||
dict(
|
||||
config={'repo_url': 'http://example.com/', 'edit_uri': '#edit/master/'},
|
||||
edit_url='http://example.com/#edit/master/testing.md',
|
||||
edit_url2='http://example.com/#edit/master/sub1/non-index.md',
|
||||
),
|
||||
dict(
|
||||
config={'edit_uri': 'http://example.com/edit/master'},
|
||||
edit_url='http://example.com/edit/master/testing.md',
|
||||
edit_url2='http://example.com/edit/master/sub1/non-index.md',
|
||||
),
|
||||
dict(
|
||||
config={'edit_uri_template': 'https://github.com/project/repo/wiki/{path_noext}'},
|
||||
edit_url='https://github.com/project/repo/wiki/testing',
|
||||
edit_url2='https://github.com/project/repo/wiki/sub1/non-index',
|
||||
),
|
||||
dict(
|
||||
config={
|
||||
'repo_url': 'https://github.com/project/repo/wiki',
|
||||
'edit_uri_template': '{path_noext}/_edit',
|
||||
},
|
||||
edit_url='https://github.com/project/repo/wiki/testing/_edit',
|
||||
edit_url2='https://github.com/project/repo/wiki/sub1/non-index/_edit',
|
||||
),
|
||||
dict(
|
||||
config={
|
||||
'repo_url': 'https://gitlab.com/project/repo',
|
||||
'edit_uri_template': '-/sse/master/docs%2F{path!q}',
|
||||
},
|
||||
edit_url='https://gitlab.com/project/repo/-/sse/master/docs%2Ftesting.md',
|
||||
edit_url2='https://gitlab.com/project/repo/-/sse/master/docs%2Fsub1%2Fnon-index.md',
|
||||
),
|
||||
dict(
|
||||
config={
|
||||
'repo_url': 'https://bitbucket.org/project/repo/',
|
||||
'edit_uri_template': 'src/master/docs/{path}?mode=edit',
|
||||
},
|
||||
edit_url='https://bitbucket.org/project/repo/src/master/docs/testing.md?mode=edit',
|
||||
edit_url2='https://bitbucket.org/project/repo/src/master/docs/sub1/non-index.md?mode=edit',
|
||||
),
|
||||
dict(
|
||||
config={
|
||||
'repo_url': 'http://example.com',
|
||||
'edit_uri': '',
|
||||
'edit_uri_template': '',
|
||||
}, # Set to blank value
|
||||
edit_url=None,
|
||||
edit_url2=None,
|
||||
),
|
||||
dict(config={}, edit_url=None, edit_url2=None), # Nothing defined
|
||||
]:
|
||||
for i, path in enumerate(paths, 1):
|
||||
edit_url_key = f'edit_url{i}' if i > 1 else 'edit_url'
|
||||
with self.subTest(case['config'], path=path):
|
||||
cfg = load_config(**case['config'])
|
||||
fl = File(path, cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls'])
|
||||
pg = Page('Foo', fl, cfg)
|
||||
self.assertEqual(pg.url, paths[path])
|
||||
self.assertEqual(pg.edit_url, case[edit_url_key])
|
||||
|
||||
@unittest.skipUnless(sys.platform.startswith("win"), "requires Windows")
|
||||
def test_page_edit_url_windows(self):
|
||||
self.test_page_edit_url(
|
||||
paths={'testing.md': 'testing/', 'sub1\\non-index.md': 'sub1/non-index/'}
|
||||
)
|
||||
|
||||
def test_page_edit_url_warning(self):
|
||||
for case in [
|
||||
dict(
|
||||
config={'edit_uri': 'edit/master'},
|
||||
edit_url='edit/master/testing.md',
|
||||
warning="WARNING:mkdocs.structure.pages:edit_uri: "
|
||||
"'edit/master/testing.md' is not a valid URL, it should include the http:// (scheme)",
|
||||
),
|
||||
]:
|
||||
with self.subTest(case['config']):
|
||||
with self.assertLogs('mkdocs') as cm:
|
||||
cfg = load_config(**case['config'])
|
||||
fl = File(
|
||||
'testing.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls']
|
||||
)
|
||||
pg = Page('Foo', fl, cfg)
|
||||
self.assertEqual(pg.url, 'testing/')
|
||||
self.assertEqual(pg.edit_url, case['edit_url'])
|
||||
self.assertEqual(cm.output, [case['warning']])
|
||||
|
||||
def test_page_render(self):
|
||||
cfg = load_config()
|
||||
fl = File('testing.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls'])
|
||||
pg = Page('Foo', fl, cfg)
|
||||
pg.read_source(cfg)
|
||||
self.assertEqual(pg.content, None)
|
||||
self.assertEqual(pg.toc, [])
|
||||
pg.render(cfg, [fl])
|
||||
self.assertTrue(
|
||||
pg.content.startswith('<h1 id="welcome-to-mkdocs">Welcome to MkDocs</h1>\n')
|
||||
)
|
||||
self.assertEqual(
|
||||
str(pg.toc).strip(),
|
||||
dedent(
|
||||
"""
|
||||
Welcome to MkDocs - #welcome-to-mkdocs
|
||||
Commands - #commands
|
||||
Project layout - #project-layout
|
||||
"""
|
||||
),
|
||||
)
|
||||
|
||||
def test_missing_page(self):
|
||||
cfg = load_config()
|
||||
fl = File('missing.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls'])
|
||||
pg = Page('Foo', fl, cfg)
|
||||
with self.assertLogs('mkdocs') as cm:
|
||||
with self.assertRaises(OSError):
|
||||
pg.read_source(cfg)
|
||||
self.assertEqual(
|
||||
'\n'.join(cm.output), 'ERROR:mkdocs.structure.pages:File not found: missing.md'
|
||||
)
|
||||
|
||||
|
||||
class SourceDateEpochTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.default = os.environ.get('SOURCE_DATE_EPOCH', None)
|
||||
os.environ['SOURCE_DATE_EPOCH'] = '0'
|
||||
|
||||
def test_source_date_epoch(self):
|
||||
cfg = load_config()
|
||||
fl = File('testing.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls'])
|
||||
pg = Page('Foo', fl, cfg)
|
||||
self.assertEqual(pg.update_date, '1970-01-01')
|
||||
|
||||
def tearDown(self):
|
||||
if self.default is not None:
|
||||
os.environ['SOURCE_DATE_EPOCH'] = self.default
|
||||
else:
|
||||
del os.environ['SOURCE_DATE_EPOCH']
|
||||
|
||||
|
||||
class RelativePathExtensionTests(unittest.TestCase):
|
||||
DOCS_DIR = os.path.join(
|
||||
os.path.abspath(os.path.dirname(__file__)), '../integration/subpages/docs'
|
||||
)
|
||||
|
||||
def get_rendered_result(self, files):
|
||||
cfg = load_config(docs_dir=self.DOCS_DIR)
|
||||
fs = [File(f, cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls']) for f in files]
|
||||
pg = Page('Foo', fs[0], cfg)
|
||||
pg.read_source(cfg)
|
||||
pg.render(cfg, Files(fs))
|
||||
return pg.content
|
||||
|
||||
@mock.patch('mkdocs.structure.pages.open', mock.mock_open(read_data='[link](non-index.md)'))
|
||||
def test_relative_html_link(self):
|
||||
self.assertEqual(
|
||||
self.get_rendered_result(['index.md', 'non-index.md']),
|
||||
'<p><a href="non-index/">link</a></p>', # No trailing /
|
||||
)
|
||||
|
||||
@mock.patch('mkdocs.structure.pages.open', mock.mock_open(read_data='[link](index.md)'))
|
||||
def test_relative_html_link_index(self):
|
||||
self.assertEqual(
|
||||
self.get_rendered_result(['non-index.md', 'index.md']),
|
||||
'<p><a href="../">link</a></p>',
|
||||
)
|
||||
|
||||
@mock.patch('mkdocs.structure.pages.open', mock.mock_open(read_data='[link](sub2/index.md)'))
|
||||
def test_relative_html_link_sub_index(self):
|
||||
self.assertEqual(
|
||||
self.get_rendered_result(['index.md', 'sub2/index.md']),
|
||||
'<p><a href="sub2/">link</a></p>', # No trailing /
|
||||
)
|
||||
|
||||
@mock.patch(
|
||||
'mkdocs.structure.pages.open', mock.mock_open(read_data='[link](sub2/non-index.md)')
|
||||
)
|
||||
def test_relative_html_link_sub_page(self):
|
||||
self.assertEqual(
|
||||
self.get_rendered_result(['index.md', 'sub2/non-index.md']),
|
||||
'<p><a href="sub2/non-index/">link</a></p>', # No trailing /
|
||||
)
|
||||
|
||||
@mock.patch('mkdocs.structure.pages.open', mock.mock_open(read_data='[link](file%20name.md)'))
|
||||
def test_relative_html_link_with_encoded_space(self):
|
||||
self.assertEqual(
|
||||
self.get_rendered_result(['index.md', 'file name.md']),
|
||||
'<p><a href="file%20name/">link</a></p>',
|
||||
)
|
||||
|
||||
@mock.patch('mkdocs.structure.pages.open', mock.mock_open(read_data='[link](file name.md)'))
|
||||
def test_relative_html_link_with_unencoded_space(self):
|
||||
self.assertEqual(
|
||||
self.get_rendered_result(['index.md', 'file name.md']),
|
||||
'<p><a href="file%20name/">link</a></p>',
|
||||
)
|
||||
|
||||
@mock.patch('mkdocs.structure.pages.open', mock.mock_open(read_data='[link](../index.md)'))
|
||||
def test_relative_html_link_parent_index(self):
|
||||
self.assertEqual(
|
||||
self.get_rendered_result(['sub2/non-index.md', 'index.md']),
|
||||
'<p><a href="../../">link</a></p>',
|
||||
)
|
||||
|
||||
@mock.patch(
|
||||
'mkdocs.structure.pages.open', mock.mock_open(read_data='[link](non-index.md#hash)')
|
||||
)
|
||||
def test_relative_html_link_hash(self):
|
||||
self.assertEqual(
|
||||
self.get_rendered_result(['index.md', 'non-index.md']),
|
||||
'<p><a href="non-index/#hash">link</a></p>',
|
||||
)
|
||||
|
||||
@mock.patch(
|
||||
'mkdocs.structure.pages.open', mock.mock_open(read_data='[link](sub2/index.md#hash)')
|
||||
)
|
||||
def test_relative_html_link_sub_index_hash(self):
|
||||
self.assertEqual(
|
||||
self.get_rendered_result(['index.md', 'sub2/index.md']),
|
||||
'<p><a href="sub2/#hash">link</a></p>',
|
||||
)
|
||||
|
||||
@mock.patch(
|
||||
'mkdocs.structure.pages.open', mock.mock_open(read_data='[link](sub2/non-index.md#hash)')
|
||||
)
|
||||
def test_relative_html_link_sub_page_hash(self):
|
||||
self.assertEqual(
|
||||
self.get_rendered_result(['index.md', 'sub2/non-index.md']),
|
||||
'<p><a href="sub2/non-index/#hash">link</a></p>',
|
||||
)
|
||||
|
||||
@mock.patch('mkdocs.structure.pages.open', mock.mock_open(read_data='[link](#hash)'))
|
||||
def test_relative_html_link_hash_only(self):
|
||||
self.assertEqual(
|
||||
self.get_rendered_result(['index.md']),
|
||||
'<p><a href="#hash">link</a></p>',
|
||||
)
|
||||
|
||||
@mock.patch('mkdocs.structure.pages.open', mock.mock_open(read_data=''))
|
||||
def test_relative_image_link_from_homepage(self):
|
||||
self.assertEqual(
|
||||
self.get_rendered_result(['index.md', 'image.png']),
|
||||
'<p><img alt="image" src="image.png" /></p>', # no opening ./
|
||||
)
|
||||
|
||||
@mock.patch('mkdocs.structure.pages.open', mock.mock_open(read_data=''))
|
||||
def test_relative_image_link_from_subpage(self):
|
||||
self.assertEqual(
|
||||
self.get_rendered_result(['sub2/non-index.md', 'image.png']),
|
||||
'<p><img alt="image" src="../../image.png" /></p>',
|
||||
)
|
||||
|
||||
@mock.patch('mkdocs.structure.pages.open', mock.mock_open(read_data=''))
|
||||
def test_relative_image_link_from_sibling(self):
|
||||
self.assertEqual(
|
||||
self.get_rendered_result(['non-index.md', 'image.png']),
|
||||
'<p><img alt="image" src="../image.png" /></p>',
|
||||
)
|
||||
|
||||
@mock.patch('mkdocs.structure.pages.open', mock.mock_open(read_data='*__not__ a link*.'))
|
||||
def test_no_links(self):
|
||||
self.assertEqual(
|
||||
self.get_rendered_result(['index.md']),
|
||||
'<p><em><strong>not</strong> a link</em>.</p>',
|
||||
)
|
||||
|
||||
@mock.patch('mkdocs.structure.pages.open', mock.mock_open(read_data='[link](non-existent.md)'))
|
||||
def test_bad_relative_html_link(self):
|
||||
with self.assertLogs('mkdocs') as cm:
|
||||
self.assertEqual(
|
||||
self.get_rendered_result(['index.md']),
|
||||
'<p><a href="non-existent.md">link</a></p>',
|
||||
)
|
||||
self.assertEqual(
|
||||
'\n'.join(cm.output),
|
||||
"WARNING:mkdocs.structure.pages:Documentation file 'index.md' contains a link "
|
||||
"to 'non-existent.md' which is not found in the documentation files.",
|
||||
)
|
||||
|
||||
@mock.patch(
|
||||
'mkdocs.structure.pages.open',
|
||||
mock.mock_open(read_data='[external](http://example.com/index.md)'),
|
||||
)
|
||||
def test_external_link(self):
|
||||
self.assertEqual(
|
||||
self.get_rendered_result(['index.md']),
|
||||
'<p><a href="http://example.com/index.md">external</a></p>',
|
||||
)
|
||||
|
||||
@mock.patch(
|
||||
'mkdocs.structure.pages.open', mock.mock_open(read_data='[absolute link](/path/to/file.md)')
|
||||
)
|
||||
def test_absolute_link(self):
|
||||
self.assertEqual(
|
||||
self.get_rendered_result(['index.md']),
|
||||
'<p><a href="/path/to/file.md">absolute link</a></p>',
|
||||
)
|
||||
|
||||
@mock.patch(
|
||||
'mkdocs.structure.pages.open',
|
||||
mock.mock_open(read_data='[absolute local path](\\image.png)'),
|
||||
)
|
||||
def test_absolute_win_local_path(self):
|
||||
self.assertEqual(
|
||||
self.get_rendered_result(['index.md']),
|
||||
'<p><a href="\\image.png">absolute local path</a></p>',
|
||||
)
|
||||
|
||||
@mock.patch('mkdocs.structure.pages.open', mock.mock_open(read_data='<mail@example.com>'))
|
||||
def test_email_link(self):
|
||||
self.assertEqual(
|
||||
self.get_rendered_result(['index.md']),
|
||||
# Markdown's default behavior is to obscure email addresses by entity-encoding them.
|
||||
# The following is equivalent to: '<p><a href="mailto:mail@example.com">mail@example.com</a></p>'
|
||||
'<p><a href="mailto:mail@e'
|
||||
'xample.com">mail@'
|
||||
'example.com</a></p>',
|
||||
)
|
||||
@ -0,0 +1,198 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import unittest
|
||||
|
||||
from mkdocs.structure.toc import get_toc
|
||||
from mkdocs.tests.base import dedent, get_markdown_toc
|
||||
|
||||
|
||||
class TableOfContentsTests(unittest.TestCase):
|
||||
def test_indented_toc(self):
|
||||
md = dedent(
|
||||
"""
|
||||
# Heading 1
|
||||
## Heading 2
|
||||
### Heading 3
|
||||
"""
|
||||
)
|
||||
expected = dedent(
|
||||
"""
|
||||
Heading 1 - #heading-1
|
||||
Heading 2 - #heading-2
|
||||
Heading 3 - #heading-3
|
||||
"""
|
||||
)
|
||||
toc = get_toc(get_markdown_toc(md))
|
||||
self.assertEqual(str(toc).strip(), expected)
|
||||
self.assertEqual(len(toc), 1)
|
||||
|
||||
def test_indented_toc_html(self):
|
||||
md = dedent(
|
||||
"""
|
||||
# Heading 1
|
||||
## <code>Heading</code> 2
|
||||
## Heading 3
|
||||
"""
|
||||
)
|
||||
expected = dedent(
|
||||
"""
|
||||
Heading 1 - #heading-1
|
||||
Heading 2 - #heading-2
|
||||
Heading 3 - #heading-3
|
||||
"""
|
||||
)
|
||||
toc = get_toc(get_markdown_toc(md))
|
||||
self.assertEqual(str(toc).strip(), expected)
|
||||
self.assertEqual(len(toc), 1)
|
||||
|
||||
def test_flat_toc(self):
|
||||
md = dedent(
|
||||
"""
|
||||
# Heading 1
|
||||
# Heading 2
|
||||
# Heading 3
|
||||
"""
|
||||
)
|
||||
expected = dedent(
|
||||
"""
|
||||
Heading 1 - #heading-1
|
||||
Heading 2 - #heading-2
|
||||
Heading 3 - #heading-3
|
||||
"""
|
||||
)
|
||||
toc = get_toc(get_markdown_toc(md))
|
||||
self.assertEqual(str(toc).strip(), expected)
|
||||
self.assertEqual(len(toc), 3)
|
||||
|
||||
def test_flat_h2_toc(self):
|
||||
md = dedent(
|
||||
"""
|
||||
## Heading 1
|
||||
## Heading 2
|
||||
## Heading 3
|
||||
"""
|
||||
)
|
||||
expected = dedent(
|
||||
"""
|
||||
Heading 1 - #heading-1
|
||||
Heading 2 - #heading-2
|
||||
Heading 3 - #heading-3
|
||||
"""
|
||||
)
|
||||
toc = get_toc(get_markdown_toc(md))
|
||||
self.assertEqual(str(toc).strip(), expected)
|
||||
self.assertEqual(len(toc), 3)
|
||||
|
||||
def test_mixed_toc(self):
|
||||
md = dedent(
|
||||
"""
|
||||
# Heading 1
|
||||
## Heading 2
|
||||
# Heading 3
|
||||
### Heading 4
|
||||
### Heading 5
|
||||
"""
|
||||
)
|
||||
expected = dedent(
|
||||
"""
|
||||
Heading 1 - #heading-1
|
||||
Heading 2 - #heading-2
|
||||
Heading 3 - #heading-3
|
||||
Heading 4 - #heading-4
|
||||
Heading 5 - #heading-5
|
||||
"""
|
||||
)
|
||||
toc = get_toc(get_markdown_toc(md))
|
||||
self.assertEqual(str(toc).strip(), expected)
|
||||
self.assertEqual(len(toc), 2)
|
||||
|
||||
def test_mixed_html(self):
|
||||
md = dedent(
|
||||
"""
|
||||
# Heading 1
|
||||
## Heading 2
|
||||
# Heading 3
|
||||
### Heading 4
|
||||
### <a>Heading 5</a>
|
||||
"""
|
||||
)
|
||||
expected = dedent(
|
||||
"""
|
||||
Heading 1 - #heading-1
|
||||
Heading 2 - #heading-2
|
||||
Heading 3 - #heading-3
|
||||
Heading 4 - #heading-4
|
||||
Heading 5 - #heading-5
|
||||
"""
|
||||
)
|
||||
toc = get_toc(get_markdown_toc(md))
|
||||
self.assertEqual(str(toc).strip(), expected)
|
||||
self.assertEqual(len(toc), 2)
|
||||
|
||||
def test_nested_anchor(self):
|
||||
md = dedent(
|
||||
"""
|
||||
# Heading 1
|
||||
## Heading 2
|
||||
# Heading 3
|
||||
### Heading 4
|
||||
### <a href="/">Heading 5</a>
|
||||
"""
|
||||
)
|
||||
expected = dedent(
|
||||
"""
|
||||
Heading 1 - #heading-1
|
||||
Heading 2 - #heading-2
|
||||
Heading 3 - #heading-3
|
||||
Heading 4 - #heading-4
|
||||
Heading 5 - #heading-5
|
||||
"""
|
||||
)
|
||||
toc = get_toc(get_markdown_toc(md))
|
||||
self.assertEqual(str(toc).strip(), expected)
|
||||
self.assertEqual(len(toc), 2)
|
||||
|
||||
def test_entityref(self):
|
||||
md = dedent(
|
||||
"""
|
||||
# Heading & 1
|
||||
## Heading > 2
|
||||
### Heading < 3
|
||||
"""
|
||||
)
|
||||
expected = dedent(
|
||||
"""
|
||||
Heading & 1 - #heading-1
|
||||
Heading > 2 - #heading-2
|
||||
Heading < 3 - #heading-3
|
||||
"""
|
||||
)
|
||||
toc = get_toc(get_markdown_toc(md))
|
||||
self.assertEqual(str(toc).strip(), expected)
|
||||
self.assertEqual(len(toc), 1)
|
||||
|
||||
def test_charref(self):
|
||||
md = '# @Header'
|
||||
expected = '@Header - #header'
|
||||
toc = get_toc(get_markdown_toc(md))
|
||||
self.assertEqual(str(toc).strip(), expected)
|
||||
self.assertEqual(len(toc), 1)
|
||||
|
||||
def test_level(self):
|
||||
md = dedent(
|
||||
"""
|
||||
# Heading 1
|
||||
## Heading 1.1
|
||||
### Heading 1.1.1
|
||||
### Heading 1.1.2
|
||||
## Heading 1.2
|
||||
"""
|
||||
)
|
||||
toc = get_toc(get_markdown_toc(md))
|
||||
|
||||
def get_level_sequence(items):
|
||||
for item in items:
|
||||
yield item.level
|
||||
yield from get_level_sequence(item.children)
|
||||
|
||||
self.assertEqual(tuple(get_level_sequence(toc)), (1, 2, 3, 3, 2))
|
||||
Reference in New Issue
Block a user