def test_get_files_exclude_readme_with_index(self, tdir): config = load_config(docs_dir=tdir) files = get_files(config) 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)
def test_build_sitemap_template(self, mock_gzip_open, mock_build_template, mock_write_file): cfg = load_config() env = cfg['theme'].get_env() build._build_theme_template('sitemap.xml', env, mock.Mock(), cfg, mock.Mock()) mock_write_file.assert_called_once() mock_build_template.assert_called_once() mock_gzip_open.assert_called_once()
def test_not_use_directory_urls(self): md_text = 'An [internal link](internal.md) to another document.' expected = '<p>An <a href="internal/index.html">internal link</a> to another document.</p>' config = load_config(pages=['index.md', 'internal.md'], use_directory_urls=False) page, nav = build_page(None, 'index.md', config, md_text) page.render(config, nav) self.assertEqual(page.content.strip(), expected.strip())
def test_ignore_external_link(self): md_text = 'An [external link](http://example.com/external.md).' expected = '<p>An <a href="http://example.com/external.md">external link</a>.</p>' config = load_config(pages=[{'Home': 'index.md'}]) page, nav = build_page(None, 'index.md', config, md_text) page.render(config, nav) self.assertEqual(page.content.strip(), expected.strip())
def test_edit_uri_fragment_windows(self): pages = [ 'index.md', 'internal.md', 'sub\\internal.md', 'sub1\\sub2\\internal.md', ] # Ensure fragment strings are supported repo_url = 'http://example.com' edit_uri = '#fragment/edit/master/docs/' site_navigation = nav.SiteNavigation(load_config( pages=pages, repo_url=repo_url, edit_uri=edit_uri, site_dir='site', site_url='', use_directory_urls=True )) expected_results = ( repo_url + edit_uri + pages[0], repo_url + edit_uri + pages[1], repo_url + edit_uri + pages[2].replace('\\', '/'), repo_url + edit_uri + pages[3].replace('\\', '/'), ) for idx, page in enumerate(site_navigation.walk_pages()): self.assertEqual(page.edit_url, expected_results[idx])
def test_populate_page_dirty_modified(self, site_dir): cfg = load_config(site_dir=site_dir) file = File('testing.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls']) page = Page('Foo', file, cfg) build._populate_page(page, cfg, Files([file]), dirty=True) self.assertTrue(page.markdown.startswith('# Welcome to MkDocs')) self.assertTrue(page.content.startswith('<h1 id="welcome-to-mkdocs">Welcome to MkDocs</h1>'))
def test_indented_toc(self): pages = [ {'Home': 'index.md'}, {'API Guide': [ {'Running': 'api-guide/running.md'}, {'Testing': 'api-guide/testing.md'}, {'Debugging': 'api-guide/debugging.md'}, ]}, {'About': [ {'Release notes': 'about/release-notes.md'}, {'License': 'about/license.md'} ]} ] expected = dedent(""" Home - / API Guide Running - /api-guide/running/ Testing - /api-guide/testing/ Debugging - /api-guide/debugging/ About Release notes - /about/release-notes/ License - /about/license/ """) site_navigation = nav.SiteNavigation(load_config(pages=pages)) self.assertEqual(str(site_navigation).strip(), expected) self.assertEqual(len(site_navigation.nav_items), 3) self.assertEqual(len(site_navigation.pages), 6)
def test_edit_uri_query_string(self): pages = [ 'index.md', 'internal.md', 'sub/internal.md', 'sub1/sub2/internal.md', ] # Ensure query strings are supported repo_url = 'http://example.com' edit_uri = '?query=edit/master/docs/' site_navigation = nav.SiteNavigation(load_config( pages=pages, repo_url=repo_url, edit_uri=edit_uri, site_dir='site', site_url='', use_directory_urls=True )) expected_results = ( repo_url + edit_uri + pages[0], repo_url + edit_uri + pages[1], repo_url + edit_uri + pages[2], repo_url + edit_uri + pages[3], ) for idx, page in enumerate(site_navigation.walk_pages()): self.assertEqual(page.edit_url, expected_results[idx])
def test_convert_multiple_internal_links(self): md_text = '[First link](first.md) [second link](second.md).' expected = '<p><a href="first/">First link</a> <a href="second/">second link</a>.</p>' config = load_config(pages=['index.md', 'first.md', 'second.md']) page, nav = build_page(None, 'index.md', config, md_text) page.render(config, nav) self.assertEqual(page.content.strip(), expected.strip())
def test_generate_site_navigation(self): """ Verify inferring page titles based on the filename """ pages = [ 'index.md', 'api-guide/running.md', 'about/notes.md', 'about/sub/license.md', ] url_context = nav.URLContext() nav_items, pages = nav._generate_site_navigation(load_config(pages=pages), url_context) self.assertEqual([n.title for n in nav_items], ['Home', 'Running', 'Notes', 'License']) self.assertEqual([n.url for n in nav_items], [ '.', 'api-guide/running/', 'about/notes/', 'about/sub/license/' ]) self.assertEqual([p.title for p in pages], ['Home', 'Running', 'Notes', 'License'])
def test_deploy_ignore_version(self, mock_import, check_version, get_remote, get_sha, is_repo): config = load_config( remote_branch='test', ) gh_deploy.gh_deploy(config, ignore_version=True) check_version.assert_not_called()
def test_deploy_ignore_version_default(self, mock_import, check_version, get_remote, get_sha, is_repo): config = load_config( remote_branch='test', ) gh_deploy.gh_deploy(config) check_version.assert_called_once()
def test_deploy_no_cname(self, mock_isfile, mock_import, get_remote, get_sha, is_repo): config = load_config( remote_branch='test', ) gh_deploy.gh_deploy(config)
def test_create_media_urls(self): expected_results = { 'https://media.cdn.org/jq.js': [ 'https://media.cdn.org/jq.js', 'https://media.cdn.org/jq.js', 'https://media.cdn.org/jq.js' ], 'http://media.cdn.org/jquery.js': [ 'http://media.cdn.org/jquery.js', 'http://media.cdn.org/jquery.js', 'http://media.cdn.org/jquery.js' ], '//media.cdn.org/jquery.js': [ '//media.cdn.org/jquery.js', '//media.cdn.org/jquery.js', '//media.cdn.org/jquery.js' ], 'media.cdn.org/jquery.js': [ 'media.cdn.org/jquery.js', 'media.cdn.org/jquery.js', '../media.cdn.org/jquery.js' ], 'local/file/jquery.js': [ 'local/file/jquery.js', 'local/file/jquery.js', '../local/file/jquery.js' ], 'local\\windows\\file\\jquery.js': [ 'local/windows/file/jquery.js', 'local/windows/file/jquery.js', '../local/windows/file/jquery.js' ], 'image.png': [ 'image.png', 'image.png', '../image.png' ], 'style.css?v=20180308c': [ 'style.css?v=20180308c', 'style.css?v=20180308c', '../style.css?v=20180308c' ], '#some_id': [ '#some_id', '#some_id', '#some_id' ] } cfg = load_config(use_directory_urls=False) pages = [ Page('Home', File('index.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls']), cfg), Page('About', File('about.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls']), cfg), Page('FooBar', File('foo/bar.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls']), cfg) ] for i, page in enumerate(pages): urls = utils.create_media_urls(expected_results.keys(), page) self.assertEqual([v[i] for v in expected_results.values()], urls)
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'] self.assertIsInstance(files, Files) self.assertEqual(len(files), len(expected)) self.assertEqual([f.src_path for f in files], expected)
def test_convert_internal_link_differing_directory(self): md_text = 'An [internal link](../internal.md) to another document.' expected = '<p>An <a href="../internal/">internal link</a> to another document.</p>' config = load_config(pages=['foo/bar.md', 'internal.md']) page, nav = build_page(None, 'foo/bar.md', config, md_text) page.render(config) self.assertEqual(page.content.strip(), expected.strip())
def test_convert_internal_link(self): md_text = 'An [internal link](internal.md) to another document.' expected = '<p>An <a href="internal/">internal link</a> to another document.</p>' config = load_config(pages=['index.md', 'internal.md']) page, nav = build_page(None, 'index.md', config, md_text) page.render(config, nav) self.assertEqual(page.content.strip(), expected.strip())
def test_base_url(self): pages = [ 'index.md' ] site_navigation = nav.SiteNavigation(load_config(pages=pages, use_directory_urls=False)) base_url = site_navigation.url_context.make_relative('/') self.assertEqual(base_url, '.')
def test_BOM(self): docs_dir = tempfile.mkdtemp() site_dir = tempfile.mkdtemp() try: # Create an UTF-8 Encoded file with BOM (as Micorsoft editors do). See #1186. f = io.open(os.path.join(docs_dir, 'index.md'), 'w', encoding='utf-8-sig') f.write('# An UTF-8 encoded file with a BOM') f.close() cfg = load_config( docs_dir=docs_dir, site_dir=site_dir ) build.build(cfg) # Verify that the file was generated properly. # If the BOM is not removed, Markdown will return: # `<p>\ufeff# An UTF-8 encoded file with a BOM</p>`. f = io.open(os.path.join(site_dir, 'index.html'), 'r', encoding='utf-8') output = f.read() f.close() self.assertTrue( '<h1 id="an-utf-8-encoded-file-with-a-bom">An UTF-8 encoded file with a BOM</h1>' in output ) finally: shutil.rmtree(docs_dir) shutil.rmtree(site_dir)
def test_force_abs_urls_with_base(self): """ Verify force absolute URLs """ pages = [ 'index.md', 'api-guide/running.md', 'about/notes.md', 'about/sub/license.md', ] url_context = nav.URLContext() url_context.force_abs_urls = True url_context.base_path = '/foo/' nav_items, pages = nav._generate_site_navigation(load_config(pages=pages), url_context) self.assertEqual([n.title for n in nav_items], ['Home', 'Running', 'Notes', 'License']) self.assertEqual([n.url for n in nav_items], [ '/foo/', '/foo/api-guide/running/', '/foo/about/notes/', '/foo/about/sub/license/' ])
def test_strict_mode_valid(self): pages = [ 'index.md', 'internal.md', 'sub/internal.md', ] md_text = "[test](internal.md)" config = load_config(pages=pages, strict=False) page, nav = build_page(None, 'index.md', config, md_text) page.render(config, nav) config = load_config(pages=pages, strict=True) page, nav = build_page(None, 'index.md', config, md_text) page.render(config, nav)
def test_edit_uri_sub_dir_missing_slash(self): pages = [ 'index.md', 'internal.md', 'sub/internal.md', 'sub1/sub2/internal.md', ] # Basic test repo_url = 'http://example.com/foo' edit_uri = 'edit/master/docs' site_navigation = nav.SiteNavigation(load_config( pages=pages, repo_url=repo_url, edit_uri=edit_uri, site_dir='site', site_url='', use_directory_urls=True )) expected_results = ( repo_url + '/' + edit_uri + '/' + pages[0], repo_url + '/' + edit_uri + '/' + pages[1], repo_url + '/' + edit_uri + '/' + pages[2], repo_url + '/' + edit_uri + '/' + pages[3], ) for idx, page in enumerate(site_navigation.walk_pages()): self.assertEqual(page.edit_url, expected_results[idx])
def test_copying_media(self): with TemporaryDirectory() as docs_dir, TemporaryDirectory() as site_dir: # Create a non-empty markdown file, image, html file, dot file and dot directory. f = open(os.path.join(docs_dir, 'index.md'), 'w') f.write(dedent(""" page_title: custom title # Heading 1 This is some text. # Heading 2 And some more text. """)) f.close() open(os.path.join(docs_dir, 'img.jpg'), 'w').close() open(os.path.join(docs_dir, 'example.html'), 'w').close() open(os.path.join(docs_dir, '.hidden'), 'w').close() os.mkdir(os.path.join(docs_dir, '.git')) open(os.path.join(docs_dir, '.git/hidden'), 'w').close() cfg = load_config(docs_dir=docs_dir, site_dir=site_dir) build.build(cfg) # Verify only the markdown (coverted to html) and the image are copied. self.assertTrue(os.path.isfile(os.path.join(site_dir, 'index.html'))) self.assertTrue(os.path.isfile(os.path.join(site_dir, 'img.jpg'))) self.assertTrue(os.path.isfile(os.path.join(site_dir, 'example.html'))) self.assertFalse(os.path.isfile(os.path.join(site_dir, '.hidden'))) self.assertFalse(os.path.isfile(os.path.join(site_dir, '.git/hidden')))
def test_edit_uri_sub_dir_missing_slash_windows(self): pages = [ 'index.md', 'internal.md', 'sub\\internal.md', 'sub1\\sub2\\internal.md', ] # Ensure the '/' is added to the repo_url and edit_uri repo_url = 'http://example.com/foo' edit_uri = 'edit/master/docs' site_navigation = nav.SiteNavigation(load_config( pages=pages, repo_url=repo_url, edit_uri=edit_uri, site_dir='site', site_url='', use_directory_urls=True )) expected_results = ( repo_url + '/' + edit_uri + '/' + pages[0], repo_url + '/' + edit_uri + '/' + pages[1], repo_url + '/' + edit_uri + '/' + pages[2].replace('\\', '/'), repo_url + '/' + edit_uri + '/' + pages[3].replace('\\', '/'), ) for idx, page in enumerate(site_navigation.walk_pages()): self.assertEqual(page.edit_url, expected_results[idx])
def test_copy_theme_files(self): docs_dir = tempfile.mkdtemp() site_dir = tempfile.mkdtemp() try: # Create a non-empty markdown file. f = open(os.path.join(docs_dir, 'index.md'), 'w') f.write(dedent(""" page_title: custom title # Heading 1 This is some text. """)) f.close() cfg = load_config(docs_dir=docs_dir, site_dir=site_dir) build.build(cfg) # Verify only theme media are copied, not templates or Python files. self.assertTrue(os.path.isfile(os.path.join(site_dir, 'index.html'))) self.assertTrue(os.path.isdir(os.path.join(site_dir, 'js'))) self.assertTrue(os.path.isdir(os.path.join(site_dir, 'css'))) self.assertTrue(os.path.isdir(os.path.join(site_dir, 'img'))) self.assertFalse(os.path.isfile(os.path.join(site_dir, '__init__.py'))) self.assertFalse(os.path.isfile(os.path.join(site_dir, '__init__.pyc'))) self.assertFalse(os.path.isfile(os.path.join(site_dir, 'base.html'))) self.assertFalse(os.path.isfile(os.path.join(site_dir, 'content.html'))) self.assertFalse(os.path.isfile(os.path.join(site_dir, 'nav.html'))) finally: shutil.rmtree(docs_dir) shutil.rmtree(site_dir)
def test_populate_page_dirty_not_modified(self, site_dir, docs_dir): cfg = load_config(docs_dir=docs_dir, site_dir=site_dir) file = File('index.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls']) page = Page('Foo', file, cfg) build._populate_page(page, cfg, Files([file]), dirty=True) # Content is empty as file read was skipped self.assertEqual(page.markdown, None) self.assertEqual(page.content, None)
def test_markdown_duplicate_custom_extension(self): """ Duplicated extension names should not cause problems. """ md_text = "foo" config = load_config(pages=[{'Home': 'index.md'}], markdown_extensions=['toc']) page, nav = build_page(None, 'index.md', config, md_text) page.render(config, nav) self.assertEqual(page.content.strip(), '<p>foo</p>')
def get_rendered_result(self, files): cfg = load_config(docs_dir=self.DOCS_DIR) fs = [] for f in files: fs.append(File(f.replace('/', os.sep), cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls'])) pg = Page('Foo', fs[0], cfg) pg.read_source(cfg) pg.render(cfg, Files(fs)) return pg.content
def test_empty_document(self): config = load_config(pages=[{'Home': 'index.md'}]) page, nav = build_page(None, 'index.md', config) page.render(config, nav) self.assertEqual(page.content, '') self.assertEqual(len(list(page.toc)), 0) self.assertEqual(page.meta, {}) self.assertEqual(page.title, 'Home')
def test_strict_mode_invalid(self): pages = [ 'index.md', 'internal.md', 'sub/internal.md', ] md_text = "[test](bad_link.md)" config = load_config(pages=pages, strict=False) page, nav = build_page(None, 'index.md', config, md_text) page.render(config, nav) config = load_config(pages=pages, strict=True) page, nav = build_page(None, 'index.md', config, md_text) self.assertRaises( MarkdownNotFound, page.render, config, nav)
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_context_extra_css_js_from_nested_page(self): nav_cfg = [ {'Home': 'index.md'}, {'Nested': 'foo/bar.md'} ] cfg = load_config( nav=nav_cfg, extra_css=['style.css'], extra_javascript=['script.js'], use_directory_urls=False ) files = Files([ File('index.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls']), File('foo/bar.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls']) ]) nav = get_navigation(files, cfg) context = build.get_context(nav, files, cfg, nav.pages[1]) self.assertEqual(context['extra_css'], ['../style.css']) self.assertEqual(context['extra_javascript'], ['../script.js'])
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/') files = Files([ File(item, cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls']) for item in nav_cfg ]) 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='/')")
def test_build_page_error(self, site_dir, mock_write_file): cfg = load_config(site_dir=site_dir, nav=['index.md'], plugins=[]) files = Files([ File('index.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls']) ]) nav = get_navigation(files, cfg) page = files.documentation_pages()[0].page # Fake populate page page.title = 'Title' page.markdown = 'page content' page.content = '<p>page content</p>' with self.assertLogs('mkdocs', level='ERROR') as cm: self.assertRaises(OSError, build._build_page, page, cfg, files, nav, self._get_env_with_null_translations(cfg)) self.assertEqual(cm.output, [ "ERROR:mkdocs.commands.build:Error building page 'index.md': Error message." ]) mock_write_file.assert_called_once()
def test_build_page_dirty_not_modified(self, site_dir, mock_write_file): cfg = load_config(site_dir=site_dir, nav=['testing.md'], plugins=[]) files = Files([ File('testing.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls']) ]) nav = get_navigation(files, cfg) page = files.documentation_pages()[0].page # Fake populate page page.title = 'Title' page.markdown = 'page content' page.content = '<p>page content</p>' build._build_page(page, cfg, files, nav, self._get_env_with_null_translations(cfg), dirty=True) mock_write_file.assert_called_once()
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/') files = Files([ File( list(item.values())[0], cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls']) for item in nav_cfg ]) 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_nested_ungrouped_nav(self): nav_cfg = [ {'Home': 'test.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/') files = Files( [File(list(item.values())[0], cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls']) for item in nav_cfg] ) 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_dont_convert_code_block_urls(self): pages = [ 'index.md', 'internal.md', 'sub/internal.md', ] config = load_config(pages=pages) site_navigation = nav.SiteNavigation(config) expected = dedent(""" <p>An HTML Anchor::</p> <pre><code><a href="index.md">My example link</a> </code></pre> """) for page in site_navigation.walk_pages(): page.markdown = 'An HTML Anchor::\n\n <a href="index.md">My example link</a>\n' page.render(config, site_navigation) self.assertEqual(page.content, expected)
def test_nested_ungrouped(self): pages = [ { 'Home': 'index.md' }, { 'Contact': 'about/contact.md' }, { 'License Title': 'about/sub/license.md' }, ] expected = dedent(""" Home - / Contact - /about/contact/ License Title - /about/sub/license/ """) site_navigation = nav.SiteNavigation(load_config(pages=pages)) self.assertEqual(str(site_navigation).strip(), expected) self.assertEqual(len(site_navigation.nav_items), 3) self.assertEqual(len(site_navigation.pages), 3)
def test_copying_media(self): docs_dir = tempfile.mkdtemp() site_dir = tempfile.mkdtemp() try: # Create a non-empty markdown file, image, html file, dot file and dot directory. f = open(os.path.join(docs_dir, 'index.md'), 'w') f.write( dedent(""" page_title: custom title # Heading 1 This is some text. # Heading 2 And some more text. """)) f.close() open(os.path.join(docs_dir, 'img.jpg'), 'w').close() open(os.path.join(docs_dir, 'example.html'), 'w').close() open(os.path.join(docs_dir, '.hidden'), 'w').close() os.mkdir(os.path.join(docs_dir, '.git')) open(os.path.join(docs_dir, '.git/hidden'), 'w').close() cfg = load_config(docs_dir=docs_dir, site_dir=site_dir) build.build(cfg) # Verify only the markdown (coverted to html) and the image are copied. self.assertTrue( os.path.isfile(os.path.join(site_dir, 'index.html'))) self.assertTrue(os.path.isfile(os.path.join(site_dir, 'img.jpg'))) self.assertTrue( os.path.isfile(os.path.join(site_dir, 'example.html'))) self.assertFalse(os.path.isfile(os.path.join(site_dir, '.hidden'))) self.assertFalse( os.path.isfile(os.path.join(site_dir, '.git/hidden'))) finally: shutil.rmtree(docs_dir) shutil.rmtree(site_dir)
def test_force_abs_urls(self): """ Verify force absolute URLs """ pages = [ 'index.md', 'api-guide/running.md', 'about/notes.md', 'about/sub/license.md', ] url_context = nav.URLContext() url_context.force_abs_urls = True nav_items, pages = nav._generate_site_navigation( load_config(pages=pages), url_context) self.assertEqual([n.title for n in nav_items], ['Home', 'Running', 'Notes', 'License']) self.assertEqual([n.url for n in nav_items], [ '/', '/api-guide/running/', '/about/notes/', '/about/sub/license/' ])
def test_generate_site_navigation_windows(self): """ Verify inferring page titles based on the filename with a windows path """ pages = [ 'index.md', 'api-guide\\running.md', 'about\\notes.md', 'about\\sub\\license.md', ] url_context = nav.URLContext() nav_items, pages = nav._generate_site_navigation( load_config(pages=pages), url_context) self.assertEqual([n.title for n in nav_items], ['Home', 'Running', 'Notes', 'License']) self.assertEqual( [n.url for n in nav_items], ['.', 'api-guide/running/', 'about/notes/', 'about/sub/license/']) self.assertEqual([p.title for p in pages], ['Home', 'Running', 'Notes', 'License'])
def test_create_media_urls(self): pages = [ {'Home': 'index.md'}, {'About': 'about.md'}, {'Sub': [ {'Sub Home': 'index.md'}, {'Sub About': 'about.md'}, ]} ] expected_results = { 'https://media.cdn.org/jq.js': 'https://media.cdn.org/jq.js', 'http://media.cdn.org/jquery.js': 'http://media.cdn.org/jquery.js', '//media.cdn.org/jquery.js': '//media.cdn.org/jquery.js', 'media.cdn.org/jquery.js': './media.cdn.org/jquery.js', 'local/file/jquery.js': './local/file/jquery.js', 'image.png': './image.png', } site_navigation = nav.SiteNavigation(load_config(pages=pages)) for path, expected_result in expected_results.items(): urls = utils.create_media_urls(site_navigation, [path]) self.assertEqual(urls[0], expected_result)
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/') files = Files([ File('index.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls']) ]) 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), 1)
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_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_copy_theme_files(self): docs_dir = tempfile.mkdtemp() site_dir = tempfile.mkdtemp() try: # Create a non-empty markdown file. f = open(os.path.join(docs_dir, 'index.md'), 'w') f.write( dedent(""" page_title: custom title # Heading 1 This is some text. """)) f.close() cfg = load_config(docs_dir=docs_dir, site_dir=site_dir) build.build(cfg) # Verify only theme media are copied, not templates or Python files. self.assertTrue( os.path.isfile(os.path.join(site_dir, 'index.html'))) self.assertTrue(os.path.isdir(os.path.join(site_dir, 'js'))) self.assertTrue(os.path.isdir(os.path.join(site_dir, 'css'))) self.assertTrue(os.path.isdir(os.path.join(site_dir, 'img'))) self.assertFalse( os.path.isfile(os.path.join(site_dir, '__init__.py'))) self.assertFalse( os.path.isfile(os.path.join(site_dir, '__init__.pyc'))) self.assertFalse( os.path.isfile(os.path.join(site_dir, 'base.html'))) self.assertFalse( os.path.isfile(os.path.join(site_dir, 'content.html'))) self.assertFalse(os.path.isfile(os.path.join(site_dir, 'nav.html'))) finally: shutil.rmtree(docs_dir) shutil.rmtree(site_dir)
def test_convert_markdown(self): """ Ensure that basic Markdown -> HTML and TOC works. """ md_text = dedent(""" title: custom title # Heading 1 This is some text. # Heading 2 And some more text. """) config = load_config(pages=[{'Home': 'index.md'}]) page, nav = build_page(None, 'index.md', config, md_text) page.render(config, nav) expected_html = dedent(""" <h1 id="heading-1">Heading 1</h1> <p>This is some text.</p> <h1 id="heading-2">Heading 2</h1> <p>And some more text.</p> """) expected_toc = dedent(""" Heading 1 - #heading-1 Heading 2 - #heading-2 """) expected_meta = {'title': 'custom title'} self.assertEqual(page.content.strip(), expected_html) self.assertEqual(str(page.toc).strip(), expected_toc) self.assertEqual(page.meta, expected_meta) self.assertEqual(page.title, 'custom title')
def test_build_page_dirty_modified(self, site_dir, docs_dir, mock_write_file): cfg = load_config(docs_dir=docs_dir, site_dir=site_dir, nav=['test.md'], plugins=[]) files = Files([ File('test.md', cfg['docs_dir'], cfg['site_dir'], cfg['use_directory_urls']) ]) nav = get_navigation(files, cfg) page = files.documentation_pages()[0].page # Fake populate page page.title = 'Title' page.markdown = 'new page content' page.content = '<p>new page content</p>' build._build_page(page, cfg, files, nav, cfg['theme'].get_env(), dirty=True) mock_write_file.assert_not_called()
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_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_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_create_relative_media_url_sub_index(self): ''' test special case where there's a sub/index.md page ''' pages = [ {'Home': 'index.md'}, {'Sub': [ {'Sub Home': '/subpage/index.md'}, ]} ] site_navigation = nav.SiteNavigation(load_config(pages=pages)) site_navigation.url_context.set_current_url('/subpage/') site_navigation.file_context.current_file = "subpage/index.md" def assertPathGenerated(declared, expected): url = utils.create_relative_media_url(site_navigation, declared) self.assertEqual(url, expected) assertPathGenerated("img.png", "./img.png") assertPathGenerated("./img.png", "./img.png") assertPathGenerated("/img.png", "../img.png")
def test_indented_toc(self): pages = [{ 'Home': 'index.md' }, { 'API Guide': [ { 'Running': 'api-guide/running.md' }, { 'Testing': 'api-guide/testing.md' }, { 'Debugging': 'api-guide/debugging.md' }, ] }, { 'About': [{ 'Release notes': 'about/release-notes.md' }, { 'License': 'about/license.md' }] }] expected = dedent(""" Home - / API Guide Running - /api-guide/running/ Testing - /api-guide/testing/ Debugging - /api-guide/debugging/ About Release notes - /about/release-notes/ License - /about/license/ """) site_navigation = nav.SiteNavigation(load_config(pages=pages)) self.assertEqual(str(site_navigation).strip(), expected) self.assertEqual(len(site_navigation.nav_items), 3) self.assertEqual(len(site_navigation.pages), 6)
def test_extension_config(self): """ Test that a dictionary of 'markdown_extensions' is recognized as both a list of extensions and a dictionary of extnesion configs. """ md_text = dedent(""" # A Header """) expected_html = dedent(""" <h1 id="a-header">A Header<a class="headerlink" href="#a-header" title="Permanent link">¶</a></h1> """) config = load_config(pages=[{ 'Home': 'index.md' }], markdown_extensions=[{ 'toc': { 'permalink': True } }]) page, nav = build_page(None, 'index.md', config, md_text) page.render(config, nav) self.assertEqual(page.content.strip(), expected_html)
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, '/testing/') self.assertEqual(pg.canonical_url, 'https://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_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, '/metadata/') self.assertEqual(pg.canonical_url, 'https://example.com/metadata/') 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_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, '/sub1/') self.assertEqual(pg.canonical_url, 'https://example.com/sub1/') 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_markdown_table_extension(self): """ Ensure that the table extension is supported. """ md_text = dedent(""" First Header | Second Header -------------- | -------------- Content Cell 1 | Content Cell 2 Content Cell 3 | Content Cell 4 """) expected_html = dedent(""" <table> <thead> <tr> <th>First Header</th> <th>Second Header</th> </tr> </thead> <tbody> <tr> <td>Content Cell 1</td> <td>Content Cell 2</td> </tr> <tr> <td>Content Cell 3</td> <td>Content Cell 4</td> </tr> </tbody> </table> """) config = load_config(pages=[{'Home': 'index.md'}]) page, nav = build_page(None, 'index.md', config, md_text) page.render(config, nav) self.assertEqual(page.content.strip(), expected_html)
def test_convert_internal_asbolute_media(self): """Test absolute image URL's are correct for different base_urls""" pages = [ 'index.md', 'internal.md', 'sub/internal.md', ] config = load_config(pages=pages) site_navigation = nav.SiteNavigation(config) expected_results = ( './img/initial-layout.png', '../img/initial-layout.png', '../../img/initial-layout.png', ) template = '<p><img alt="The initial MkDocs layout" src="%s" /></p>' for (page, expected) in zip(site_navigation.walk_pages(), expected_results): page.markdown = '![The initial MkDocs layout](/img/initial-layout.png)' page.render(config, site_navigation) self.assertEqual(page.content, template % expected)