Commits

Oben Sonne committed 80c3446

Add a simple test suite

The test suite simple initializes and builds the Poole template project
and checks if the generated files are as expected.

  • Participants
  • Parent commits d122dec

Comments (0)

Files changed (17)

 syntax: regexp
+^tests/actual$
+^tests/errors.diff$
 \.pyc$
 ~$
 ^.project$

File tests/expected/input/blog.2010-02-22.Doctors_in_my_penguin.md

+
+
+---
+## {{ page["post"] }}
+
+*Posted at
+<!--%
+from datetime import datetime
+print datetime.strptime(page["date"], "%Y-%m-%d").strftime("%B %d, %Y")
+%-->*
+
+There is a bank in my eel, your argument is invalid.
+
+More nonsense at <http://automeme.net/>.

File tests/expected/input/blog.2010-03-01.I_ate_all the pokemans.md

+
+
+## {{ page["post"] }}
+
+*Posted at <!--{ page["date"] }-->.*
+
+What *are* interior crocodile alligators? We just don't know.
+
+More nonsense at <http://automeme.net/>.

File tests/expected/input/blog.md

+
+menu-position: 10
+---
+Poole has basic blog support. If an input page's file name has a structure like
+`page-title.YYYY-MM-DD.post-title.md`, e.g. `blog.201010-02-27.read_this.md`,
+Poole recognizes the date and post title and sets them as attributes of the
+page. These attributes can then be used to generate a list of blog posts:
+
+<!--%
+from datetime import datetime
+posts = [p for p in pages if "post" in p] # get all blog post pages
+posts.sort(key=lambda p: p.get("date"), reverse=True) # sort post pages by date
+for p in posts:
+    date = datetime.strptime(p.date, "%Y-%m-%d").strftime("%B %d, %Y")
+    print "  * **[%s](%s)** - %s" % (p.post, p.url, date) # markdown list item
+%-->
+
+Have a look into `input/blog.md` to see how it works. Feel free to adjust it
+to your needs.

File tests/expected/input/index.md

+
+title: home
+menu-position: 0
+---
+
+## Welcome to Poole
+
+In Poole you write your pages in [markdown][md]. It's easier to write
+markdown than HTML.
+
+Poole is made for simple websites you just want to get done, without installing
+a bunch of requirements and without learning a template engine.
+
+In a build, Poole copies every file from the *input* directory to the *output*
+directory. During that process every markdown file (ending with *md*, *mkd*,
+*mdown* or *markdown*) is converted to HTML using the project's `page.html`
+as a skeleton.
+
+[md]: http://daringfireball.net/projects/markdown/

File tests/expected/input/layout.md

+
+menu-position: 3
+---
+Every page of a poole site is based on *one global template file*, `page.html`.
+All you need to adjust the site layout is to
+
+ * edit the page template `page.html` and
+ * extend or edit the style file `input/poole.css`.

File tests/expected/input/logic.md

+
+menu-position: 4
+---
+Poole has basic support for content generation using Python code inlined in
+page files. This is everything but a clear separation of logic and content but
+for simple sites this is just a pragmatic way to get things done fast.
+For instance the menu on this page is generated by some inlined Python code in
+the project's `page.html` file.
+
+Just ignore this feature if you don't need it :)
+
+Content generation by inlined Python code is good to add some zest to your
+site. If you use it a lot, you better go with more sophisticated site
+generators like [Hyde](http://ringce.com/hyde).

File tests/expected/input/poole.css

+
+body {
+    font-family: sans;
+    width: 800px;
+    margin: 1em auto;
+    color: #2e3436;
+}
+div#box {
+    border: solid #2e3436 1px;
+}
+div#header, div#menu, div#content, div#footer {
+    padding: 1em;
+}
+div#menu {
+    background-color: #2e3436;
+    padding: 0.6em 0 0.6em 0;
+}
+#menu span {
+    background-color: #2e3436;
+    font-weight: bold;
+    padding: 0.6em;
+}
+#menu span.current {
+    background-color: #555753;
+}
+#menu a {
+    color: #fefefc;
+    text-decoration: none;
+}
+div#footer {
+    color: gray;
+    text-align: center;
+    font-size: small;
+}
+div#footer a {
+    color: gray;
+    text-decoration: none;
+}
+pre {
+    border: dotted black 1px;
+    background: #eeeeec;
+    font-size: small;
+    padding: 1em;
+}
+

File tests/expected/output/blog.2010-02-22.Doctors_in_my_penguin.html

+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <title>poole - blog</title>
+    <meta name="description" content="a poole site" />
+    <meta name="keywords" content="poole" />
+    <link rel="stylesheet" type="text/css" href="/poole.css" />
+</head>
+<body>
+    <div id="box">
+    <div id="header">
+         <h1>a poole site</h1>
+         <h2>blog</h2>
+    </div>
+    <div id="menu">
+    <span class=""><a href="/index.html">home</a></span>
+<span class=""><a href="/layout.html">layout</a></span>
+<span class=""><a href="/logic.html">logic</a></span>
+<span class="current"><a href="/blog.html">blog</a></span>
+    </div>
+    <div id="content"><h2>Doctors in my penguin</h2>
+<p><em>Posted at
+February 22, 2010</em></p>
+<p>There is a bank in my eel, your argument is invalid.</p>
+<p>More nonsense at <a href="http://automeme.net/">http://automeme.net/</a>.</p></div>
+    </div>
+    <div id="footer">
+        Built with <a href="http://bitbucket.org/obensonne/poole">Poole</a>
+        &middot;
+        Licensed as <a href="http://creativecommons.org/licenses/by-sa/3.0">CC-SA</a>
+        &middot;
+        <a href="http://validator.w3.org/check?uri=referer">Validate me</a>
+    </div>
+</body>
+</html>

File tests/expected/output/blog.2010-03-01.I_ate_all the pokemans.html

+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <title>poole - blog</title>
+    <meta name="description" content="a poole site" />
+    <meta name="keywords" content="poole" />
+    <link rel="stylesheet" type="text/css" href="/poole.css" />
+</head>
+<body>
+    <div id="box">
+    <div id="header">
+         <h1>a poole site</h1>
+         <h2>blog</h2>
+    </div>
+    <div id="menu">
+    <span class=""><a href="/index.html">home</a></span>
+<span class=""><a href="/layout.html">layout</a></span>
+<span class=""><a href="/logic.html">logic</a></span>
+<span class="current"><a href="/blog.html">blog</a></span>
+    </div>
+    <div id="content"><h2>I ate all the pokemans</h2>
+<p><em>Posted at 2010-03-01.</em></p>
+<p>What <em>are</em> interior crocodile alligators? We just don't know.</p>
+<p>More nonsense at <a href="http://automeme.net/">http://automeme.net/</a>.</p></div>
+    </div>
+    <div id="footer">
+        Built with <a href="http://bitbucket.org/obensonne/poole">Poole</a>
+        &middot;
+        Licensed as <a href="http://creativecommons.org/licenses/by-sa/3.0">CC-SA</a>
+        &middot;
+        <a href="http://validator.w3.org/check?uri=referer">Validate me</a>
+    </div>
+</body>
+</html>

File tests/expected/output/blog.html

+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+s<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <title>poole - blog</title>
+    <meta name="description" content="a poole site" />
+    <meta name="keywords" content="poole" />
+    <link rel="stylesheet" type="text/css" href="/poole.css" />
+</head>
+<body>
+    <div id="box">
+    <div id="header">
+         <h1>a poole site</h1>
+         <h2>blog</h2>
+    </div>
+    <div id="menu">
+    <span class=""><a href="/index.html">home</a></span>
+<span class=""><a href="/layout.html">layout</a></span>
+<span class=""><a href="/logic.html">logic</a></span>
+<span class="current"><a href="/blog.html">blog</a></span>
+    </div>
+    <div id="content"><p>Poole has basic blog support. If an input page's file name has a structure like
+<code>page-title.YYYY-MM-DD.post-title.md</code>, e.g. <code>blog.201010-02-27.read_this.md</code>,
+Poole recognizes the date and post title and sets them as attributes of the
+page. These attributes can then be used to generate a list of blog posts:</p>
+<ul>
+<li><strong><a href="/blog.2010-03-01.I_ate_all the pokemans.html">I ate all the pokemans</a></strong> - March 01, 2010</li>
+<li><strong><a href="/blog.2010-02-22.Doctors_in_my_penguin.html">Doctors in my penguin</a></strong> - February 22, 2010</li>
+</ul>
+<p>Have a look into <code>input/blog.md</code> to see how it works. Feel free to adjust it
+to your needs.</p></div>
+    </div>
+    <div id="footer">
+        Built with <a href="http://bitbucket.org/obensonne/poole">Poole</a>
+        &middot;
+        Licensed as <a href="http://creativecommons.org/licenses/by-sa/3.0">CC-SA</a>
+        &middot;
+        <a href="http://validator.w3.org/check?uri=referer">Validate me</a>
+    </div>
+</body>
+</html>

File tests/expected/output/index.html

+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <title>poole - home</title>
+    <meta name="description" content="a poole site" />
+    <meta name="keywords" content="poole" />
+    <link rel="stylesheet" type="text/css" href="/poole.css" />
+</head>
+<body>
+    <div id="box">
+    <div id="header">
+         <h1>a poole site</h1>
+         <h2>home</h2>
+    </div>
+    <div id="menu">
+    <span class="current"><a href="/index.html">home</a></span>
+<span class=""><a href="/layout.html">layout</a></span>
+<span class=""><a href="/logic.html">logic</a></span>
+<span class=""><a href="/blog.html">blog</a></span>
+    </div>
+    <div id="content"><h2>Welcome to Poole</h2>
+<p>In Poole you write your pages in <a href="http://daringfireball.net/projects/markdown/">markdown</a>. It's easier to write
+markdown than HTML.</p>
+<p>Poole is made for simple websites you just want to get done, without installing
+a bunch of requirements and without learning a template engine.</p>
+<p>In a build, Poole copies every file from the <em>input</em> directory to the <em>output</em>
+directory. During that process every markdown file (ending with <em>md</em>, <em>mkd</em>,
+<em>mdown</em> or <em>markdown</em>) is converted to HTML using the project's <code>page.html</code>
+as a skeleton.</p></div>
+    </div>
+    <div id="footer">
+        Built with <a href="http://bitbucket.org/obensonne/poole">Poole</a>
+        &middot;
+        Licensed as <a href="http://creativecommons.org/licenses/by-sa/3.0">CC-SA</a>
+        &middot;
+        <a href="http://validator.w3.org/check?uri=referer">Validate me</a>
+    </div>
+</body>
+</html>

File tests/expected/output/layout.html

+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <title>poole - layout</title>
+    <meta name="description" content="a poole site" />
+    <meta name="keywords" content="poole" />
+    <link rel="stylesheet" type="text/css" href="/poole.css" />
+</head>
+<body>
+    <div id="box">
+    <div id="header">
+         <h1>a poole site</h1>
+         <h2>layout</h2>
+    </div>
+    <div id="menu">
+    <span class=""><a href="/index.html">home</a></span>
+<span class="current"><a href="/layout.html">layout</a></span>
+<span class=""><a href="/logic.html">logic</a></span>
+<span class=""><a href="/blog.html">blog</a></span>
+    </div>
+    <div id="content"><p>Every page of a poole site is based on <em>one global template file</em>, <code>page.html</code>.
+All you need to adjust the site layout is to</p>
+<ul>
+<li>edit the page template <code>page.html</code> and</li>
+<li>extend or edit the style file <code>input/poole.css</code>.</li>
+</ul></div>
+    </div>
+    <div id="footer">
+        Built with <a href="http://bitbucket.org/obensonne/poole">Poole</a>
+        &middot;
+        Licensed as <a href="http://creativecommons.org/licenses/by-sa/3.0">CC-SA</a>
+        &middot;
+        <a href="http://validator.w3.org/check?uri=referer">Validate me</a>
+    </div>
+</body>
+</html>

File tests/expected/output/logic.html

+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <title>poole - logic</title>
+    <meta name="description" content="a poole site" />
+    <meta name="keywords" content="poole" />
+    <link rel="stylesheet" type="text/css" href="/poole.css" />
+</head>
+<body>
+    <div id="box">
+    <div id="header">
+         <h1>a poole site</h1>
+         <h2>logic</h2>
+    </div>
+    <div id="menu">
+    <span class=""><a href="/index.html">home</a></span>
+<span class=""><a href="/layout.html">layout</a></span>
+<span class="current"><a href="/logic.html">logic</a></span>
+<span class=""><a href="/blog.html">blog</a></span>
+    </div>
+    <div id="content"><p>Poole has basic support for content generation using Python code inlined in
+page files. This is everything but a clear separation of logic and content but
+for simple sites this is just a pragmatic way to get things done fast.
+For instance the menu on this page is generated by some inlined Python code in
+the project's <code>page.html</code> file.</p>
+<p>Just ignore this feature if you don't need it :)</p>
+<p>Content generation by inlined Python code is good to add some zest to your
+site. If you use it a lot, you better go with more sophisticated site
+generators like <a href="http://ringce.com/hyde">Hyde</a>.</p></div>
+    </div>
+    <div id="footer">
+        Built with <a href="http://bitbucket.org/obensonne/poole">Poole</a>
+        &middot;
+        Licensed as <a href="http://creativecommons.org/licenses/by-sa/3.0">CC-SA</a>
+        &middot;
+        <a href="http://validator.w3.org/check?uri=referer">Validate me</a>
+    </div>
+</body>
+</html>

File tests/expected/output/poole.css

+
+body {
+    font-family: sans;
+    width: 800px;
+    margin: 1em auto;
+    color: #2e3436;
+}
+div#box {
+    border: solid #2e3436 1px;
+}
+div#header, div#menu, div#content, div#footer {
+    padding: 1em;
+}
+div#menu {
+    background-color: #2e3436;
+    padding: 0.6em 0 0.6em 0;
+}
+#menu span {
+    background-color: #2e3436;
+    font-weight: bold;
+    padding: 0.6em;
+}
+#menu span.current {
+    background-color: #555753;
+}
+#menu a {
+    color: #fefefc;
+    text-decoration: none;
+}
+div#footer {
+    color: gray;
+    text-align: center;
+    font-size: small;
+}
+div#footer a {
+    color: gray;
+    text-decoration: none;
+}
+pre {
+    border: dotted black 1px;
+    background: #eeeeec;
+    font-size: small;
+    padding: 1em;
+}
+

File tests/expected/page.html

+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset={{ htmlspecialchars(__encoding__) }}" />
+    <title>poole - {{ htmlspecialchars(page["title"]) }}</title>
+    <meta name="description" content="{{ htmlspecialchars(page.get("description", "a poole site")) }}" />
+    <meta name="keywords" content="{{ htmlspecialchars(page.get("keywords", "poole")) }}" />
+    <link rel="stylesheet" type="text/css" href="poole.css" />
+</head>
+<body>
+    <div id="box">
+    <div id="header">
+         <h1>a poole site</h1>
+         <h2>{{ htmlspecialchars(page["title"]) }}</h2>
+    </div>
+    <div id="menu">
+    <!--%
+        mpages = [p for p in pages if "menu-position" in p]
+        mpages.sort(key=lambda p: int(p["menu-position"]))
+        entry = '<span class="%s"><a href="%s">%s</a></span>'
+        for p in mpages:
+            style = p["title"] == page["title"] and "current" or ""
+            print(entry % (style, htmlspecialchars(p["url"]), htmlspecialchars(p["title"])))
+    %-->
+    </div>
+    <div id="content">{{ __content__ }}</div>
+    </div>
+    <div id="footer">
+        Built with <a href="http://bitbucket.org/obensonne/poole">Poole</a>
+        &middot;
+        Licensed as <a href="http://creativecommons.org/licenses/by-sa/3.0">CC-SA</a>
+        &middot;
+        <a href="http://validator.w3.org/check?uri=referer">Validate me</a>
+    </div>
+</body>
+</html>

File tests/run.py

+#!/usr/bin/env python
+
+import codecs
+import os
+import shutil
+import subprocess
+import sys
+
+HERE = os.path.dirname(__file__)
+POOLE = os.path.join(HERE, "..", "poole.py")
+ACTUAL = os.path.join(HERE, "actual")
+EXPECTED = os.path.join(HERE, "expected")
+ERRORS = os.path.join(HERE, "errors.diff")
+
+if os.path.exists(ACTUAL):
+    shutil.rmtree(ACTUAL)
+
+if os.path.exists(ERRORS):
+    os.remove(ERRORS)
+
+cmd_init = [POOLE, ACTUAL, "--init"]
+cmd_build = [POOLE, ACTUAL, "--build"]
+cmd_diff = ["diff", "-Naur", EXPECTED, ACTUAL]
+
+r = subprocess.call(cmd_init, stdout=subprocess.PIPE)
+if r != os.EX_OK:
+    sys.exit(1)
+
+r = subprocess.call(cmd_build, stdout=subprocess.PIPE)
+if r != os.EX_OK:
+    sys.exit(1)
+
+p = subprocess.Popen(cmd_diff, stdout=subprocess.PIPE)
+diff = p.communicate()[0]
+if diff:
+    with codecs.open(ERRORS, 'w', 'UTF8') as fp:
+        fp.write(diff)
+    print("failed - see %s for details" % ERRORS)
+    sys.exit(1)
+
+print("passed")