From: Vladimír Vondruš Date: Sat, 9 Dec 2017 20:58:56 +0000 (+0100) Subject: theme: tests for the global layout. X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~cjwatson/git?a=commitdiff_plain;h=f9045b1d16c8f0fe7c714a84249e0df01c29c2ad;p=blog.git theme: tests for the global layout. Otherwise the things go over my head to an unmaintainable mess pretty fast. --- diff --git a/.gitignore b/.gitignore index 3159f7f9..1e0752e8 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ +__pycache__ *.kdev4 diff --git a/doc/pelican/theme.rst b/doc/pelican/theme.rst index 3bef9bcb..364094dd 100644 --- a/doc/pelican/theme.rst +++ b/doc/pelican/theme.rst @@ -98,13 +98,6 @@ If you would want to use the light theme instead, the configuration is this and plugins are prefixed with ``M_``. Configuration variables without prefix are builtin Pelican options. -.. note-warning:: - - The above configuration should be enough to produce a (mostly empty) - version of your website using the theme without any errors during - processing. If that's not the case, please :gh:`report a bug `. - Thank you! - `Configuration`_ ================ diff --git a/pelican-theme/test/.gitignore b/pelican-theme/test/.gitignore new file mode 100644 index 00000000..beeea249 --- /dev/null +++ b/pelican-theme/test/.gitignore @@ -0,0 +1 @@ +*/output/ diff --git a/pelican-theme/test/__init__.py b/pelican-theme/test/__init__.py new file mode 100644 index 00000000..56df9d4a --- /dev/null +++ b/pelican-theme/test/__init__.py @@ -0,0 +1,60 @@ +import os +import shutil +import unittest + +from pelican import read_settings, Pelican + +class MinimalTestCase(unittest.TestCase): + def __init__(self, path, dir, *args, **kwargs): + unittest.TestCase.__init__(self, *args, **kwargs) + # Source files for test_something.py are in something_{dir}/ subdirectory + self.path = os.path.join(os.path.dirname(os.path.realpath(path)), os.path.splitext(os.path.basename(path))[0][5:] + ('_' + dir if dir else '')) + + # Display ALL THE DIFFS + self.maxDiff = None + + def setUp(self): + if os.path.exists(os.path.join(self.path, 'output')): shutil.rmtree(os.path.join(self.path, 'output')) + + def run_pelican(self, settings): + implicit_settings = { + # Contains just stuff that isn't required by the m.css theme itself, + # but is needed to have the test setup working correctly + 'RELATIVE_URLS': True, + 'TIMEZONE': 'UTC', + 'READERS': {'html': None}, + 'SITEURL': '.', + 'PATH': os.path.join(self.path), + 'OUTPUT_PATH': os.path.join(self.path, 'output'), + 'PAGE_EXCLUDES': [os.path.join(self.path, 'output')], + 'ARTICLE_EXCLUDES': [os.path.join(self.path, 'output')], + 'FEED_ALL_ATOM': None, # Don't render feeds, we're not testing them *ever* + } + settings = read_settings(path=None, override={**implicit_settings, **settings}) + pelican = Pelican(settings=settings) + pelican.run() + + def actual_expected_contents(self, actual, expected = None): + if not expected: expected = actual + + with open(os.path.join(self.path, expected)) as f: + expected_contents = f.read().strip() + with open(os.path.join(self.path, 'output', actual)) as f: + actual_contents = f.read().strip() + return actual_contents, expected_contents + +class BaseTestCase(MinimalTestCase): + def run_pelican(self, settings): + implicit_settings = { + 'THEME': '.', + 'PLUGIN_PATHS': ['../pelican-plugins'], + 'PLUGINS': ['m.htmlsanity'], + 'THEME_STATIC_DIR': 'static', + 'M_CSS_FILES': ['https://fonts.googleapis.com/css?family=Source+Code+Pro:400,400i,600%7CSource+Sans+Pro:400,400i,600,600i', + 'static/m-dark.css'], + # i.e., not rendering the category, tag and author lists as they + # are not supported anyway + 'DIRECT_TEMPLATES': ['index', 'archives'], + 'SLUGIFY_SOURCE': 'basename' + } + MinimalTestCase.run_pelican(self, {**implicit_settings, **settings}) diff --git a/pelican-theme/test/layout/features.html b/pelican-theme/test/layout/features.html new file mode 100644 index 00000000..83d8baff --- /dev/null +++ b/pelican-theme/test/layout/features.html @@ -0,0 +1,110 @@ + + + + + Features | Your Brand + + + + + + + + + + + +
+
+
+
+
+
+

Features

+
+
+
+
+
+ + + diff --git a/pelican-theme/test/layout/features.rst b/pelican-theme/test/layout/features.rst new file mode 100644 index 00000000..157365ae --- /dev/null +++ b/pelican-theme/test/layout/features.rst @@ -0,0 +1,2 @@ +Features +######## diff --git a/pelican-theme/test/layout/guest-post-howto.html b/pelican-theme/test/layout/guest-post-howto.html new file mode 100644 index 00000000..b69076cb --- /dev/null +++ b/pelican-theme/test/layout/guest-post-howto.html @@ -0,0 +1,110 @@ + + + + + Guest post howto | Your Brand + + + + + + + + + + + +
+
+
+
+
+
+

Guest post howto

+
+
+
+
+
+ + + diff --git a/pelican-theme/test/layout/guest-post-howto.rst b/pelican-theme/test/layout/guest-post-howto.rst new file mode 100644 index 00000000..04a0ece0 --- /dev/null +++ b/pelican-theme/test/layout/guest-post-howto.rst @@ -0,0 +1,2 @@ +Guest post howto +################ diff --git a/pelican-theme/test/layout/index.html b/pelican-theme/test/layout/index.html new file mode 100644 index 00000000..cc078ec5 --- /dev/null +++ b/pelican-theme/test/layout/index.html @@ -0,0 +1,111 @@ + + + + + Your Brand Blog + + + + + +
+
+
+
+
+
+

Congratulations!

+ The m.css theme is alive and kicking! Now, feed it some articles so it doesn't feel so empty :) +
+
+ +
+
+
+ + + diff --git a/pelican-theme/test/layout/showcase-requirements.html b/pelican-theme/test/layout/showcase-requirements.html new file mode 100644 index 00000000..679538f9 --- /dev/null +++ b/pelican-theme/test/layout/showcase-requirements.html @@ -0,0 +1,110 @@ + + + + + Showcase requirements | Your Brand + + + + + + + + + + + +
+
+
+
+
+
+

Showcase requirements

+
+
+
+
+
+ + + diff --git a/pelican-theme/test/layout/showcase-requirements.rst b/pelican-theme/test/layout/showcase-requirements.rst new file mode 100644 index 00000000..daa23c93 --- /dev/null +++ b/pelican-theme/test/layout/showcase-requirements.rst @@ -0,0 +1,2 @@ +Showcase requirements +##################### diff --git a/pelican-theme/test/layout_disable_blog_links/index.html b/pelican-theme/test/layout_disable_blog_links/index.html new file mode 100644 index 00000000..8304a278 --- /dev/null +++ b/pelican-theme/test/layout_disable_blog_links/index.html @@ -0,0 +1,60 @@ + + + + + A Pelican Blog + + + + + +
+
+
+
+
+
+

Congratulations!

+ The m.css theme is alive and kicking! Now, feed it some articles so it doesn't feel so empty :) +
+
+ +
+
+
+ + + diff --git a/pelican-theme/test/layout_disable_fine_print/index.html b/pelican-theme/test/layout_disable_fine_print/index.html new file mode 100644 index 00000000..b58e456e --- /dev/null +++ b/pelican-theme/test/layout_disable_fine_print/index.html @@ -0,0 +1,58 @@ + + + + + A Pelican Blog + + + + + +
+
+
+
+
+
+

Congratulations!

+ The m.css theme is alive and kicking! Now, feed it some articles so it doesn't feel so empty :) +
+
+ +
+
+
+ + + diff --git a/pelican-theme/test/layout_minimal/index.html b/pelican-theme/test/layout_minimal/index.html new file mode 100644 index 00000000..f7f10660 --- /dev/null +++ b/pelican-theme/test/layout_minimal/index.html @@ -0,0 +1,47 @@ + + + + + A Pelican Blog + + + + + + +
+
+
+
+
+
+

Congratulations!

+ The m.css theme is alive and kicking! Now, feed it some articles so it doesn't feel so empty :) +
+
+ +
+
+
+
+ + diff --git a/pelican-theme/test/layout_no_footer/index.html b/pelican-theme/test/layout_no_footer/index.html new file mode 100644 index 00000000..b60364d4 --- /dev/null +++ b/pelican-theme/test/layout_no_footer/index.html @@ -0,0 +1,37 @@ + + + + + A Pelican Blog + + + + + +
+
+
+
+
+
+

Congratulations!

+ The m.css theme is alive and kicking! Now, feed it some articles so it doesn't feel so empty :) +
+
+ +
+
+
+ + diff --git a/pelican-theme/test/layout_one_column_navbar/index.html b/pelican-theme/test/layout_one_column_navbar/index.html new file mode 100644 index 00000000..86d103a5 --- /dev/null +++ b/pelican-theme/test/layout_one_column_navbar/index.html @@ -0,0 +1,57 @@ + + + + + A Pelican Blog + + + + + +
+
+
+
+
+
+

Congratulations!

+ The m.css theme is alive and kicking! Now, feed it some articles so it doesn't feel so empty :) +
+
+ +
+
+
+
+ + diff --git a/pelican-theme/test/test_layout.py b/pelican-theme/test/test_layout.py new file mode 100644 index 00000000..333a2564 --- /dev/null +++ b/pelican-theme/test/test_layout.py @@ -0,0 +1,153 @@ +import os + +from test import MinimalTestCase, BaseTestCase + +class Layout(BaseTestCase): + def __init__(self, *args, **kwargs): + super().__init__(__file__, '', *args, **kwargs) + + def test(self): + self.run_pelican({ + 'SITENAME': 'Your Brand', + 'M_BLOG_NAME': 'Your Brand Blog', + 'M_SITE_LOGO_TEXT': 'Your.brand', + 'M_LINKS_NAVBAR1': [ + ('Features', 'features.html', 'features', []), + ('Showcase', '#', 'showcase', [ + ('Requirements', 'showcase-requirements.html', 'showcase-requirements'), + ('Live demo', 'http://demo.your.brand/', ''), + ('Get a quote', 'mailto:you@your.brand', '')]), + ('Download', '#', 'download', [])], + 'M_LINKS_NAVBAR2': [('Blog', 'archives.html', '[blog]', [ + ('News', '#', ''), + ('Archive', '#', ''), + ('Write a guest post', 'guest-post-howto.html', 'guest-post-howto')]), + ('Contact', '#', 'contact', [])], + 'M_LINKS_FOOTER1': [('Your Brand', 'index.html'), + ('Mission', '#'), + ('', ''), + ('The People', '#')], + 'M_LINKS_FOOTER2':[('Features', 'features.html'), + ('', ''), + ('Live demo', 'http://demo.your.brand/'), + ('Requirements', 'showcase-requirements.html')], + 'M_LINKS_FOOTER3': [('Download', ''), + ('Packages', '#'), + ('', ''), + ('Source', '#')], + 'M_LINKS_FOOTER4':[('Contact', ''), + ('E-mail', 'mailto:you@your.brand'), + ('', ''), + ('GitHub', 'https://github.com/your-brand')], + # multiline to test indentation + 'M_FINE_PRINT': """ +Your Brand. Copyright © `You `_, 2017. +All rights reserved. +""", + 'PAGE_PATHS': ['.'], + 'PAGE_SAVE_AS': '{slug}.html', + 'PAGE_URL': '{slug}.html', + 'ARTICLE_PATHS': ['articles'] # doesn't exist + }) + + # - page title is M_BLOG_NAME for index, as it is a blog page + # - the Blog entry should be highlighted + # - mailto and external URL links should not have SITEURL prepended in + # both top navbar and bottom navigation + # - footer spacers should put   there + # - again, the archives page and index page should be exactly the same + self.assertEqual(*self.actual_expected_contents('index.html')) + self.assertEqual(*self.actual_expected_contents('archives.html', 'index.html')) + + # - page title is SITENAME, as these are pages + # - corresponding items in top navbar should be highlighted + self.assertEqual(*self.actual_expected_contents('features.html')) + self.assertEqual(*self.actual_expected_contents('showcase-requirements.html')) + self.assertEqual(*self.actual_expected_contents('guest-post-howto.html')) + +class Minimal(MinimalTestCase): + def __init__(self, *args, **kwargs): + super().__init__(__file__, 'minimal', *args, **kwargs) + + def test(self): + self.run_pelican({ + # This is the minimal that's required. Not even the M_THEME_COLOR + # is required. + 'THEME': '.', + 'PLUGIN_PATHS': ['../pelican-plugins'], + 'PLUGINS': ['m.htmlsanity'], + 'THEME_STATIC_DIR': 'static', + 'M_CSS_FILES': ['https://fonts.googleapis.com/css?family=Source+Code+Pro:400,400i,600%7CSource+Sans+Pro:400,400i,600,600i', + 'static/m-dark.css'], + 'M_THEME_COLOR': '#22272e'}) + + # The archives and index page should be exactly the same + self.assertEqual(*self.actual_expected_contents('index.html')) + self.assertEqual(*self.actual_expected_contents('archives.html', 'index.html')) + + # Verify that we're *really* using the default setup and not disabling + # any pages -- but don't verify the page content, as these are not + # supported anyway + self.assertTrue(os.path.exists(os.path.join(self.path, 'output/authors.html'))) + self.assertTrue(os.path.exists(os.path.join(self.path, 'output/categories.html'))) + self.assertTrue(os.path.exists(os.path.join(self.path, 'output/tags.html'))) + + # The CSS files should be copied along + self.assertTrue(os.path.exists(os.path.join(self.path, 'output/static/m-grid.css'))) + self.assertTrue(os.path.exists(os.path.join(self.path, 'output/static/m-components.css'))) + self.assertTrue(os.path.exists(os.path.join(self.path, 'output/static/m-dark.css'))) + self.assertTrue(os.path.exists(os.path.join(self.path, 'output/static/pygments-dark.css'))) + +class OneColumnNavbar(BaseTestCase): + def __init__(self, *args, **kwargs): + super().__init__(__file__, 'one_column_navbar', *args, **kwargs) + + def test(self): + self.run_pelican({ + 'M_LINKS_NAVBAR1': [ + ('Features', '#', 'features', []), + ('A long item caption that really should not wrap on small screen', '#', '', []), + ('Blog', 'archives.html', '[blog]', [])] + }) + + # The navbar should be full 12 columns + self.assertEqual(*self.actual_expected_contents('index.html')) + +class NoFooter(BaseTestCase): + def __init__(self, *args, **kwargs): + super().__init__(__file__, 'no_footer', *args, **kwargs) + + def test(self): + self.run_pelican({ + 'M_FINE_PRINT': None + }) + + # There should be no footer at all + self.assertEqual(*self.actual_expected_contents('index.html')) + +class DisableFinePrint(BaseTestCase): + def __init__(self, *args, **kwargs): + super().__init__(__file__, 'disable_fine_print', *args, **kwargs) + + def test(self): + self.run_pelican({ + 'M_LINKS_FOOTER1': [('Your Brand', 'index.html')], + 'M_FINE_PRINT': None + }) + + # There should be footer with just the first and last column and no + # fine print + self.assertEqual(*self.actual_expected_contents('index.html')) + +class DisableBlogLinks(BaseTestCase): + def __init__(self, *args, **kwargs): + super().__init__(__file__, 'disable_blog_links', *args, **kwargs) + + def test(self): + self.run_pelican({ + 'M_LINKS_FOOTER1': [('Your Brand', 'index.html')], + 'M_LINKS_FOOTER4': None, + }) + + # There should be just the first column + self.assertEqual(*self.actual_expected_contents('index.html')) diff --git a/site/.gitignore b/site/.gitignore index ee56e815..09d62879 100644 --- a/site/.gitignore +++ b/site/.gitignore @@ -1,4 +1,3 @@ -__pycache__ *.pid output published