chiark / gitweb /
theme: tests for the global layout.
authorVladimír Vondruš <mosra@centrum.cz>
Sat, 9 Dec 2017 20:58:56 +0000 (21:58 +0100)
committerVladimír Vondruš <mosra@centrum.cz>
Mon, 11 Dec 2017 01:48:25 +0000 (02:48 +0100)
Otherwise the things go over my head to an unmaintainable mess pretty
fast.

18 files changed:
.gitignore
doc/pelican/theme.rst
pelican-theme/test/.gitignore [new file with mode: 0644]
pelican-theme/test/__init__.py [new file with mode: 0644]
pelican-theme/test/layout/features.html [new file with mode: 0644]
pelican-theme/test/layout/features.rst [new file with mode: 0644]
pelican-theme/test/layout/guest-post-howto.html [new file with mode: 0644]
pelican-theme/test/layout/guest-post-howto.rst [new file with mode: 0644]
pelican-theme/test/layout/index.html [new file with mode: 0644]
pelican-theme/test/layout/showcase-requirements.html [new file with mode: 0644]
pelican-theme/test/layout/showcase-requirements.rst [new file with mode: 0644]
pelican-theme/test/layout_disable_blog_links/index.html [new file with mode: 0644]
pelican-theme/test/layout_disable_fine_print/index.html [new file with mode: 0644]
pelican-theme/test/layout_minimal/index.html [new file with mode: 0644]
pelican-theme/test/layout_no_footer/index.html [new file with mode: 0644]
pelican-theme/test/layout_one_column_navbar/index.html [new file with mode: 0644]
pelican-theme/test/test_layout.py [new file with mode: 0644]
site/.gitignore

index 3159f7f9a5333962bbb421fa45444b5192b92d4f..1e0752e841f7fa0e76bb2311db48bbfd45e5efc0 100644 (file)
@@ -1 +1,2 @@
+__pycache__
 *.kdev4
index 3bef9bcbe1976f12d271966e9b0f194855eafb36..364094dde733dd8084e2feba1bdba3d1febaaf03 100644 (file)
@@ -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 <mosra/m.css/issues/new>`.
-    Thank you!
-
 `Configuration`_
 ================
 
diff --git a/pelican-theme/test/.gitignore b/pelican-theme/test/.gitignore
new file mode 100644 (file)
index 0000000..beeea24
--- /dev/null
@@ -0,0 +1 @@
+*/output/
diff --git a/pelican-theme/test/__init__.py b/pelican-theme/test/__init__.py
new file mode 100644 (file)
index 0000000..56df9d4
--- /dev/null
@@ -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 (file)
index 0000000..83d8baf
--- /dev/null
@@ -0,0 +1,110 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>Features | Your Brand</title>
+  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Code+Pro:400,400i,600%7CSource+Sans+Pro:400,400i,600,600i" />
+  <link rel="stylesheet" href="static/m-dark.css" />
+  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+  <meta property="og:title" content="Features" />
+  <meta name="twitter:title" content="Features" />
+  <meta property="og:url" content="features.html" />
+  <meta name="twitter:url" content="features.html" />
+  <meta name="twitter:card" content="summary" />
+  <meta property="og:type" content="website" />
+</head>
+<body>
+<header><nav id="navigation">
+  <div class="m-container">
+    <div class="m-row">
+      <a href="./" id="m-navbar-brand" class="m-col-t-9 m-col-m-none m-left-m">Your.brand</a>
+      <a id="m-navbar-show" href="#navigation" title="Show navigation" class="m-col-t-3 m-hide-m m-text-right"></a>
+      <a id="m-navbar-hide" href="#" title="Hide navigation" class="m-col-t-3 m-hide-m m-text-right"></a>
+      <div id="m-navbar-collapse" class="m-col-t-12 m-show-m m-col-m-none m-right-m">
+        <div class="m-row">
+          <ol class="m-col-t-6 m-col-m-none">
+            <li><a href="features.html" id="m-navbar-current">Features</a></li>
+            <li>
+              <a href="./">Showcase</a>
+              <ol>
+                <li><a href="showcase-requirements.html">Requirements</a></li>
+                <li><a href="http://demo.your.brand/">Live demo</a></li>
+                <li><a href="mailto:you@your.brand">Get a quote</a></li>
+              </ol>
+            </li>
+            <li><a href="./">Download</a></li>
+          </ol>
+          <ol class="m-col-t-6 m-col-m-none" start="4">
+            <li>
+              <a href="archives.html">Blog</a>
+              <ol>
+                <li><a href="./">News</a></li>
+                <li><a href="./">Archive</a></li>
+                <li><a href="guest-post-howto.html">Write a guest post</a></li>
+              </ol>
+            </li>
+            <li><a href="./">Contact</a></li>
+          </ol>
+        </div>
+      </div>
+    </div>
+  </div>
+</nav></header>
+<main>
+<article>
+  <div class="m-container m-container-inflatable">
+    <div class="m-row">
+      <div class="m-col-l-10 m-push-l-1">
+        <h1>Features</h1>
+      </div>
+    </div>
+  </div>
+</article>
+</main>
+<footer><nav>
+  <div class="m-container">
+    <div class="m-row">
+      <div class="m-col-s-3 m-col-t-6">
+        <h3><a href="index.html">Your Brand</a></h3>
+        <ul>
+          <li><a href="./">Mission</a></li>
+          <li>&nbsp;</li>
+          <li><a href="./">The People</a></li>
+        </ul>
+      </div>
+      <div class="m-col-s-3 m-col-t-6">
+        <h3><a href="features.html">Features</a></h3>
+        <ul>
+          <li>&nbsp;</li>
+          <li><a href="http://demo.your.brand/">Live demo</a></li>
+          <li><a href="showcase-requirements.html">Requirements</a></li>
+        </ul>
+      </div>
+      <div class="m-clearfix-t"></div>
+      <div class="m-col-s-3 m-col-t-6">
+        <h3>Download</h3>
+        <ul>
+          <li><a href="./">Packages</a></li>
+          <li>&nbsp;</li>
+          <li><a href="./">Source</a></li>
+        </ul>
+      </div>
+      <div class="m-col-s-3 m-col-t-6">
+        <h3>Contact</h3>
+        <ul>
+          <li><a href="mailto:you@your.brand">E-mail</a></li>
+          <li>&nbsp;</li>
+          <li><a href="https://github.com/your-brand">GitHub</a></li>
+        </ul>
+      </div>
+    </div>
+    <div class="m-row">
+      <div class="m-col-l-10 m-push-l-1">
+        <p>Your Brand. Copyright © <a href="mailto:you&#64;your.brand">You</a>, 2017.
+        All rights reserved.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/pelican-theme/test/layout/features.rst b/pelican-theme/test/layout/features.rst
new file mode 100644 (file)
index 0000000..157365a
--- /dev/null
@@ -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 (file)
index 0000000..b69076c
--- /dev/null
@@ -0,0 +1,110 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>Guest post howto | Your Brand</title>
+  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Code+Pro:400,400i,600%7CSource+Sans+Pro:400,400i,600,600i" />
+  <link rel="stylesheet" href="static/m-dark.css" />
+  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+  <meta property="og:title" content="Guest post howto" />
+  <meta name="twitter:title" content="Guest post howto" />
+  <meta property="og:url" content="guest-post-howto.html" />
+  <meta name="twitter:url" content="guest-post-howto.html" />
+  <meta name="twitter:card" content="summary" />
+  <meta property="og:type" content="website" />
+</head>
+<body>
+<header><nav id="navigation">
+  <div class="m-container">
+    <div class="m-row">
+      <a href="./" id="m-navbar-brand" class="m-col-t-9 m-col-m-none m-left-m">Your.brand</a>
+      <a id="m-navbar-show" href="#navigation" title="Show navigation" class="m-col-t-3 m-hide-m m-text-right"></a>
+      <a id="m-navbar-hide" href="#" title="Hide navigation" class="m-col-t-3 m-hide-m m-text-right"></a>
+      <div id="m-navbar-collapse" class="m-col-t-12 m-show-m m-col-m-none m-right-m">
+        <div class="m-row">
+          <ol class="m-col-t-6 m-col-m-none">
+            <li><a href="features.html">Features</a></li>
+            <li>
+              <a href="./">Showcase</a>
+              <ol>
+                <li><a href="showcase-requirements.html">Requirements</a></li>
+                <li><a href="http://demo.your.brand/">Live demo</a></li>
+                <li><a href="mailto:you@your.brand">Get a quote</a></li>
+              </ol>
+            </li>
+            <li><a href="./">Download</a></li>
+          </ol>
+          <ol class="m-col-t-6 m-col-m-none" start="4">
+            <li>
+              <a href="archives.html">Blog</a>
+              <ol>
+                <li><a href="./">News</a></li>
+                <li><a href="./">Archive</a></li>
+                <li><a href="guest-post-howto.html" id="m-navbar-current">Write a guest post</a></li>
+              </ol>
+            </li>
+            <li><a href="./">Contact</a></li>
+          </ol>
+        </div>
+      </div>
+    </div>
+  </div>
+</nav></header>
+<main>
+<article>
+  <div class="m-container m-container-inflatable">
+    <div class="m-row">
+      <div class="m-col-l-10 m-push-l-1">
+        <h1>Guest post howto</h1>
+      </div>
+    </div>
+  </div>
+</article>
+</main>
+<footer><nav>
+  <div class="m-container">
+    <div class="m-row">
+      <div class="m-col-s-3 m-col-t-6">
+        <h3><a href="index.html">Your Brand</a></h3>
+        <ul>
+          <li><a href="./">Mission</a></li>
+          <li>&nbsp;</li>
+          <li><a href="./">The People</a></li>
+        </ul>
+      </div>
+      <div class="m-col-s-3 m-col-t-6">
+        <h3><a href="features.html">Features</a></h3>
+        <ul>
+          <li>&nbsp;</li>
+          <li><a href="http://demo.your.brand/">Live demo</a></li>
+          <li><a href="showcase-requirements.html">Requirements</a></li>
+        </ul>
+      </div>
+      <div class="m-clearfix-t"></div>
+      <div class="m-col-s-3 m-col-t-6">
+        <h3>Download</h3>
+        <ul>
+          <li><a href="./">Packages</a></li>
+          <li>&nbsp;</li>
+          <li><a href="./">Source</a></li>
+        </ul>
+      </div>
+      <div class="m-col-s-3 m-col-t-6">
+        <h3>Contact</h3>
+        <ul>
+          <li><a href="mailto:you@your.brand">E-mail</a></li>
+          <li>&nbsp;</li>
+          <li><a href="https://github.com/your-brand">GitHub</a></li>
+        </ul>
+      </div>
+    </div>
+    <div class="m-row">
+      <div class="m-col-l-10 m-push-l-1">
+        <p>Your Brand. Copyright © <a href="mailto:you&#64;your.brand">You</a>, 2017.
+        All rights reserved.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/pelican-theme/test/layout/guest-post-howto.rst b/pelican-theme/test/layout/guest-post-howto.rst
new file mode 100644 (file)
index 0000000..04a0ece
--- /dev/null
@@ -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 (file)
index 0000000..cc078ec
--- /dev/null
@@ -0,0 +1,111 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>Your Brand Blog</title>
+  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Code+Pro:400,400i,600%7CSource+Sans+Pro:400,400i,600,600i" />
+  <link rel="stylesheet" href="static/m-dark.css" />
+  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+</head>
+<body>
+<header><nav id="navigation">
+  <div class="m-container">
+    <div class="m-row">
+      <a href="./" id="m-navbar-brand" class="m-col-t-9 m-col-m-none m-left-m">Your.brand</a>
+      <a id="m-navbar-show" href="#navigation" title="Show navigation" class="m-col-t-3 m-hide-m m-text-right"></a>
+      <a id="m-navbar-hide" href="#" title="Hide navigation" class="m-col-t-3 m-hide-m m-text-right"></a>
+      <div id="m-navbar-collapse" class="m-col-t-12 m-show-m m-col-m-none m-right-m">
+        <div class="m-row">
+          <ol class="m-col-t-6 m-col-m-none">
+            <li><a href="features.html">Features</a></li>
+            <li>
+              <a href="./">Showcase</a>
+              <ol>
+                <li><a href="showcase-requirements.html">Requirements</a></li>
+                <li><a href="http://demo.your.brand/">Live demo</a></li>
+                <li><a href="mailto:you@your.brand">Get a quote</a></li>
+              </ol>
+            </li>
+            <li><a href="./">Download</a></li>
+          </ol>
+          <ol class="m-col-t-6 m-col-m-none" start="4">
+            <li>
+              <a href="archives.html" id="m-navbar-current">Blog</a>
+              <ol>
+                <li><a href="./">News</a></li>
+                <li><a href="./">Archive</a></li>
+                <li><a href="guest-post-howto.html">Write a guest post</a></li>
+              </ol>
+            </li>
+            <li><a href="./">Contact</a></li>
+          </ol>
+        </div>
+      </div>
+    </div>
+  </div>
+</nav></header>
+<main>
+<div class="m-container">
+  <div class="m-row">
+    <div class="m-col-m-10">
+      <div class="m-note m-success">
+        <h3>Congratulations!</h3>
+        The m.css theme is alive and kicking! Now, feed it some articles so it doesn't feel so empty :)
+      </div>
+    </div>
+    <nav class="m-navpanel m-col-m-2">
+      <h3>Categories</h3>
+      <ol class="m-block-bar-m">
+        <li><em class="m-text m-dim">(none yet)</em></li>
+      </ol>
+    </nav>
+  </div>
+</div>
+</main>
+<footer><nav>
+  <div class="m-container">
+    <div class="m-row">
+      <div class="m-col-s-3 m-col-t-6">
+        <h3><a href="index.html">Your Brand</a></h3>
+        <ul>
+          <li><a href="./">Mission</a></li>
+          <li>&nbsp;</li>
+          <li><a href="./">The People</a></li>
+        </ul>
+      </div>
+      <div class="m-col-s-3 m-col-t-6">
+        <h3><a href="features.html">Features</a></h3>
+        <ul>
+          <li>&nbsp;</li>
+          <li><a href="http://demo.your.brand/">Live demo</a></li>
+          <li><a href="showcase-requirements.html">Requirements</a></li>
+        </ul>
+      </div>
+      <div class="m-clearfix-t"></div>
+      <div class="m-col-s-3 m-col-t-6">
+        <h3>Download</h3>
+        <ul>
+          <li><a href="./">Packages</a></li>
+          <li>&nbsp;</li>
+          <li><a href="./">Source</a></li>
+        </ul>
+      </div>
+      <div class="m-col-s-3 m-col-t-6">
+        <h3>Contact</h3>
+        <ul>
+          <li><a href="mailto:you@your.brand">E-mail</a></li>
+          <li>&nbsp;</li>
+          <li><a href="https://github.com/your-brand">GitHub</a></li>
+        </ul>
+      </div>
+    </div>
+    <div class="m-row">
+      <div class="m-col-l-10 m-push-l-1">
+        <p>Your Brand. Copyright © <a href="mailto:you&#64;your.brand">You</a>, 2017.
+        All rights reserved.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/pelican-theme/test/layout/showcase-requirements.html b/pelican-theme/test/layout/showcase-requirements.html
new file mode 100644 (file)
index 0000000..679538f
--- /dev/null
@@ -0,0 +1,110 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>Showcase requirements | Your Brand</title>
+  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Code+Pro:400,400i,600%7CSource+Sans+Pro:400,400i,600,600i" />
+  <link rel="stylesheet" href="static/m-dark.css" />
+  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+  <meta property="og:title" content="Showcase requirements" />
+  <meta name="twitter:title" content="Showcase requirements" />
+  <meta property="og:url" content="showcase-requirements.html" />
+  <meta name="twitter:url" content="showcase-requirements.html" />
+  <meta name="twitter:card" content="summary" />
+  <meta property="og:type" content="website" />
+</head>
+<body>
+<header><nav id="navigation">
+  <div class="m-container">
+    <div class="m-row">
+      <a href="./" id="m-navbar-brand" class="m-col-t-9 m-col-m-none m-left-m">Your.brand</a>
+      <a id="m-navbar-show" href="#navigation" title="Show navigation" class="m-col-t-3 m-hide-m m-text-right"></a>
+      <a id="m-navbar-hide" href="#" title="Hide navigation" class="m-col-t-3 m-hide-m m-text-right"></a>
+      <div id="m-navbar-collapse" class="m-col-t-12 m-show-m m-col-m-none m-right-m">
+        <div class="m-row">
+          <ol class="m-col-t-6 m-col-m-none">
+            <li><a href="features.html">Features</a></li>
+            <li>
+              <a href="./">Showcase</a>
+              <ol>
+                <li><a href="showcase-requirements.html" id="m-navbar-current">Requirements</a></li>
+                <li><a href="http://demo.your.brand/">Live demo</a></li>
+                <li><a href="mailto:you@your.brand">Get a quote</a></li>
+              </ol>
+            </li>
+            <li><a href="./">Download</a></li>
+          </ol>
+          <ol class="m-col-t-6 m-col-m-none" start="4">
+            <li>
+              <a href="archives.html">Blog</a>
+              <ol>
+                <li><a href="./">News</a></li>
+                <li><a href="./">Archive</a></li>
+                <li><a href="guest-post-howto.html">Write a guest post</a></li>
+              </ol>
+            </li>
+            <li><a href="./">Contact</a></li>
+          </ol>
+        </div>
+      </div>
+    </div>
+  </div>
+</nav></header>
+<main>
+<article>
+  <div class="m-container m-container-inflatable">
+    <div class="m-row">
+      <div class="m-col-l-10 m-push-l-1">
+        <h1>Showcase requirements</h1>
+      </div>
+    </div>
+  </div>
+</article>
+</main>
+<footer><nav>
+  <div class="m-container">
+    <div class="m-row">
+      <div class="m-col-s-3 m-col-t-6">
+        <h3><a href="index.html">Your Brand</a></h3>
+        <ul>
+          <li><a href="./">Mission</a></li>
+          <li>&nbsp;</li>
+          <li><a href="./">The People</a></li>
+        </ul>
+      </div>
+      <div class="m-col-s-3 m-col-t-6">
+        <h3><a href="features.html">Features</a></h3>
+        <ul>
+          <li>&nbsp;</li>
+          <li><a href="http://demo.your.brand/">Live demo</a></li>
+          <li><a href="showcase-requirements.html">Requirements</a></li>
+        </ul>
+      </div>
+      <div class="m-clearfix-t"></div>
+      <div class="m-col-s-3 m-col-t-6">
+        <h3>Download</h3>
+        <ul>
+          <li><a href="./">Packages</a></li>
+          <li>&nbsp;</li>
+          <li><a href="./">Source</a></li>
+        </ul>
+      </div>
+      <div class="m-col-s-3 m-col-t-6">
+        <h3>Contact</h3>
+        <ul>
+          <li><a href="mailto:you@your.brand">E-mail</a></li>
+          <li>&nbsp;</li>
+          <li><a href="https://github.com/your-brand">GitHub</a></li>
+        </ul>
+      </div>
+    </div>
+    <div class="m-row">
+      <div class="m-col-l-10 m-push-l-1">
+        <p>Your Brand. Copyright © <a href="mailto:you&#64;your.brand">You</a>, 2017.
+        All rights reserved.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/pelican-theme/test/layout/showcase-requirements.rst b/pelican-theme/test/layout/showcase-requirements.rst
new file mode 100644 (file)
index 0000000..daa23c9
--- /dev/null
@@ -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 (file)
index 0000000..8304a27
--- /dev/null
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>A Pelican Blog</title>
+  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Code+Pro:400,400i,600%7CSource+Sans+Pro:400,400i,600,600i" />
+  <link rel="stylesheet" href="static/m-dark.css" />
+  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+</head>
+<body>
+<header><nav id="navigation">
+  <div class="m-container">
+    <div class="m-row">
+      <a href="./" id="m-navbar-brand" class="m-col-t-9 m-col-m-none m-left-m">A Pelican Blog</a>
+    </div>
+  </div>
+</nav></header>
+<main>
+<div class="m-container">
+  <div class="m-row">
+    <div class="m-col-m-10">
+      <div class="m-note m-success">
+        <h3>Congratulations!</h3>
+        The m.css theme is alive and kicking! Now, feed it some articles so it doesn't feel so empty :)
+      </div>
+    </div>
+    <nav class="m-navpanel m-col-m-2">
+      <h3>Categories</h3>
+      <ol class="m-block-bar-m">
+        <li><em class="m-text m-dim">(none yet)</em></li>
+      </ol>
+    </nav>
+  </div>
+</div>
+</main>
+<footer><nav>
+  <div class="m-container">
+    <div class="m-row">
+      <div class="m-col-s-3 m-col-t-6">
+        <h3><a href="index.html">Your Brand</a></h3>
+        <ul>
+        </ul>
+      </div>
+      <div class="m-col-s-3 m-col-t-6">
+      </div>
+      <div class="m-clearfix-t"></div>
+      <div class="m-col-s-3 m-col-t-6">
+      </div>
+      <div class="m-col-s-3 m-col-t-6">
+      </div>
+    </div>
+    <div class="m-row">
+      <div class="m-col-l-10 m-push-l-1">
+        <p>A Pelican Blog. Powered by <a href="https://getpelican.com">Pelican</a> and <a href="http://mcss.mosra.cz">m.css</a>.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
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 (file)
index 0000000..b58e456
--- /dev/null
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>A Pelican Blog</title>
+  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Code+Pro:400,400i,600%7CSource+Sans+Pro:400,400i,600,600i" />
+  <link rel="stylesheet" href="static/m-dark.css" />
+  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+</head>
+<body>
+<header><nav id="navigation">
+  <div class="m-container">
+    <div class="m-row">
+      <a href="./" id="m-navbar-brand" class="m-col-t-9 m-col-m-none m-left-m">A Pelican Blog</a>
+    </div>
+  </div>
+</nav></header>
+<main>
+<div class="m-container">
+  <div class="m-row">
+    <div class="m-col-m-10">
+      <div class="m-note m-success">
+        <h3>Congratulations!</h3>
+        The m.css theme is alive and kicking! Now, feed it some articles so it doesn't feel so empty :)
+      </div>
+    </div>
+    <nav class="m-navpanel m-col-m-2">
+      <h3>Categories</h3>
+      <ol class="m-block-bar-m">
+        <li><em class="m-text m-dim">(none yet)</em></li>
+      </ol>
+    </nav>
+  </div>
+</div>
+</main>
+<footer><nav>
+  <div class="m-container">
+    <div class="m-row">
+      <div class="m-col-s-3 m-col-t-6">
+        <h3><a href="index.html">Your Brand</a></h3>
+        <ul>
+        </ul>
+      </div>
+      <div class="m-col-s-3 m-col-t-6">
+      </div>
+      <div class="m-clearfix-t"></div>
+      <div class="m-col-s-3 m-col-t-6">
+      </div>
+      <div class="m-col-s-3 m-col-t-6">
+        <h3><a href="./">Blog</a></h3>
+        <ul>
+        </ul>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/pelican-theme/test/layout_minimal/index.html b/pelican-theme/test/layout_minimal/index.html
new file mode 100644 (file)
index 0000000..f7f1066
--- /dev/null
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>A Pelican Blog</title>
+  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Code+Pro:400,400i,600%7CSource+Sans+Pro:400,400i,600,600i" />
+  <link rel="stylesheet" href="static/m-dark.css" />
+  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+  <meta name="theme-color" content="#22272e" />
+</head>
+<body>
+<header><nav id="navigation">
+  <div class="m-container">
+    <div class="m-row">
+      <a href="./" id="m-navbar-brand" class="m-col-t-9 m-col-m-none m-left-m">A Pelican Blog</a>
+    </div>
+  </div>
+</nav></header>
+<main>
+<div class="m-container">
+  <div class="m-row">
+    <div class="m-col-m-10">
+      <div class="m-note m-success">
+        <h3>Congratulations!</h3>
+        The m.css theme is alive and kicking! Now, feed it some articles so it doesn't feel so empty :)
+      </div>
+    </div>
+    <nav class="m-navpanel m-col-m-2">
+      <h3>Categories</h3>
+      <ol class="m-block-bar-m">
+        <li><em class="m-text m-dim">(none yet)</em></li>
+      </ol>
+    </nav>
+  </div>
+</div>
+</main>
+<footer><nav>
+  <div class="m-container">
+    <div class="m-row">
+      <div class="m-col-l-10 m-push-l-1">
+        <p>A Pelican Blog. Powered by <a href="https://getpelican.com">Pelican</a> and <a href="http://mcss.mosra.cz">m.css</a>.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/pelican-theme/test/layout_no_footer/index.html b/pelican-theme/test/layout_no_footer/index.html
new file mode 100644 (file)
index 0000000..b60364d
--- /dev/null
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>A Pelican Blog</title>
+  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Code+Pro:400,400i,600%7CSource+Sans+Pro:400,400i,600,600i" />
+  <link rel="stylesheet" href="static/m-dark.css" />
+  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+</head>
+<body>
+<header><nav id="navigation">
+  <div class="m-container">
+    <div class="m-row">
+      <a href="./" id="m-navbar-brand" class="m-col-t-9 m-col-m-none m-left-m">A Pelican Blog</a>
+    </div>
+  </div>
+</nav></header>
+<main>
+<div class="m-container">
+  <div class="m-row">
+    <div class="m-col-m-10">
+      <div class="m-note m-success">
+        <h3>Congratulations!</h3>
+        The m.css theme is alive and kicking! Now, feed it some articles so it doesn't feel so empty :)
+      </div>
+    </div>
+    <nav class="m-navpanel m-col-m-2">
+      <h3>Categories</h3>
+      <ol class="m-block-bar-m">
+        <li><em class="m-text m-dim">(none yet)</em></li>
+      </ol>
+    </nav>
+  </div>
+</div>
+</main>
+</body>
+</html>
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 (file)
index 0000000..86d103a
--- /dev/null
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>A Pelican Blog</title>
+  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Code+Pro:400,400i,600%7CSource+Sans+Pro:400,400i,600,600i" />
+  <link rel="stylesheet" href="static/m-dark.css" />
+  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+</head>
+<body>
+<header><nav id="navigation">
+  <div class="m-container">
+    <div class="m-row">
+      <a href="./" id="m-navbar-brand" class="m-col-t-9 m-col-m-none m-left-m">A Pelican Blog</a>
+      <a id="m-navbar-show" href="#navigation" title="Show navigation" class="m-col-t-3 m-hide-m m-text-right"></a>
+      <a id="m-navbar-hide" href="#" title="Hide navigation" class="m-col-t-3 m-hide-m m-text-right"></a>
+      <div id="m-navbar-collapse" class="m-col-t-12 m-show-m m-col-m-none m-right-m">
+        <div class="m-row">
+          <ol class="m-col-t-12 m-col-m-none">
+            <li><a href="./">Features</a></li>
+            <li><a href="./">A long item caption that really should not wrap on small screen</a></li>
+            <li><a href="archives.html" id="m-navbar-current">Blog</a></li>
+          </ol>
+        </div>
+      </div>
+    </div>
+  </div>
+</nav></header>
+<main>
+<div class="m-container">
+  <div class="m-row">
+    <div class="m-col-m-10">
+      <div class="m-note m-success">
+        <h3>Congratulations!</h3>
+        The m.css theme is alive and kicking! Now, feed it some articles so it doesn't feel so empty :)
+      </div>
+    </div>
+    <nav class="m-navpanel m-col-m-2">
+      <h3>Categories</h3>
+      <ol class="m-block-bar-m">
+        <li><em class="m-text m-dim">(none yet)</em></li>
+      </ol>
+    </nav>
+  </div>
+</div>
+</main>
+<footer><nav>
+  <div class="m-container">
+    <div class="m-row">
+      <div class="m-col-l-10 m-push-l-1">
+        <p>A Pelican Blog. Powered by <a href="https://getpelican.com">Pelican</a> and <a href="http://mcss.mosra.cz">m.css</a>.</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/pelican-theme/test/test_layout.py b/pelican-theme/test/test_layout.py
new file mode 100644 (file)
index 0000000..333a256
--- /dev/null
@@ -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 <mailto:you@your.brand>`_, 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 &nbsp; 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'))
index ee56e8154291ce2d6fc3c006072684611ff093c9..09d62879faba81fe44d1bd0e15ebfd59eb326fde 100644 (file)
@@ -1,4 +1,3 @@
-__pycache__
 *.pid
 output
 published