- {% endif %}
+
+ {% endif %}
-
+
{% endblock header %}
{% block content %}
diff --git a/tests/__init__.py b/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/content/article_with_cover_image.rst b/tests/content/article_with_cover_image.rst
new file mode 100644
index 0000000..9a07b89
--- /dev/null
+++ b/tests/content/article_with_cover_image.rst
@@ -0,0 +1,7 @@
+:title: With Cover Images
+:date: 2018-04-29 00:45
+:author: arul
+:category: foo
+:tags: footag
+:slug: with-cover-images
+:cover: /assets/images/article_cover.jpg
diff --git a/tests/content/article_with_http_cover_image.rst b/tests/content/article_with_http_cover_image.rst
new file mode 100644
index 0000000..2dcd3d9
--- /dev/null
+++ b/tests/content/article_with_http_cover_image.rst
@@ -0,0 +1,7 @@
+:title: With Cover Images
+:date: 2018-04-29 00:45
+:author: arul
+:category: foo
+:tags: footag
+:slug: with-http-cover-images
+:cover: http://example.com/cover.jpg
diff --git a/tests/content/article_with_og_image.rst b/tests/content/article_with_og_image.rst
new file mode 100644
index 0000000..56e8d0f
--- /dev/null
+++ b/tests/content/article_with_og_image.rst
@@ -0,0 +1,7 @@
+:title: With OG Cover Images
+:date: 2018-04-29 00:59
+:author: raj
+:category: bar
+:tags: bartag
+:slug: with-og-cover-images
+:og_image: /assets/images/og_cover.jpg
\ No newline at end of file
diff --git a/tests/content/article_without_cover.rst b/tests/content/article_without_cover.rst
new file mode 100644
index 0000000..4e5c002
--- /dev/null
+++ b/tests/content/article_without_cover.rst
@@ -0,0 +1,6 @@
+:title: Without Cover Images
+:date: 2018-04-29 00:55
+:author: arul
+:category: foo
+:tags: footag
+:slug: without-cover-images
diff --git a/tests/content/assets/css/myblog.css b/tests/content/assets/css/myblog.css
new file mode 100644
index 0000000..e69de29
diff --git a/tests/content/assets/favicon.ico b/tests/content/assets/favicon.ico
new file mode 100644
index 0000000..e69de29
diff --git a/tests/content/assets/images/article_cover.jpg b/tests/content/assets/images/article_cover.jpg
new file mode 120000
index 0000000..22ce499
--- /dev/null
+++ b/tests/content/assets/images/article_cover.jpg
@@ -0,0 +1 @@
+cover.jpg
\ No newline at end of file
diff --git a/tests/content/assets/images/arul_author_cover.jpg b/tests/content/assets/images/arul_author_cover.jpg
new file mode 120000
index 0000000..22ce499
--- /dev/null
+++ b/tests/content/assets/images/arul_author_cover.jpg
@@ -0,0 +1 @@
+cover.jpg
\ No newline at end of file
diff --git a/tests/content/assets/images/avatar.png b/tests/content/assets/images/avatar.png
new file mode 100644
index 0000000..bb2db0c
Binary files /dev/null and b/tests/content/assets/images/avatar.png differ
diff --git a/tests/content/assets/images/bar_category_cover.jpg b/tests/content/assets/images/bar_category_cover.jpg
new file mode 120000
index 0000000..22ce499
--- /dev/null
+++ b/tests/content/assets/images/bar_category_cover.jpg
@@ -0,0 +1 @@
+cover.jpg
\ No newline at end of file
diff --git a/tests/content/assets/images/bar_tag_cover.jpg b/tests/content/assets/images/bar_tag_cover.jpg
new file mode 120000
index 0000000..22ce499
--- /dev/null
+++ b/tests/content/assets/images/bar_tag_cover.jpg
@@ -0,0 +1 @@
+cover.jpg
\ No newline at end of file
diff --git a/tests/content/assets/images/cover.jpg b/tests/content/assets/images/cover.jpg
new file mode 100644
index 0000000..e43b6d1
Binary files /dev/null and b/tests/content/assets/images/cover.jpg differ
diff --git a/tests/content/assets/images/foo_category_cover.jpg b/tests/content/assets/images/foo_category_cover.jpg
new file mode 120000
index 0000000..22ce499
--- /dev/null
+++ b/tests/content/assets/images/foo_category_cover.jpg
@@ -0,0 +1 @@
+cover.jpg
\ No newline at end of file
diff --git a/tests/content/assets/images/foo_tag_cover.jpg b/tests/content/assets/images/foo_tag_cover.jpg
new file mode 120000
index 0000000..22ce499
--- /dev/null
+++ b/tests/content/assets/images/foo_tag_cover.jpg
@@ -0,0 +1 @@
+cover.jpg
\ No newline at end of file
diff --git a/tests/content/assets/images/header_cover.jpg b/tests/content/assets/images/header_cover.jpg
new file mode 120000
index 0000000..22ce499
--- /dev/null
+++ b/tests/content/assets/images/header_cover.jpg
@@ -0,0 +1 @@
+cover.jpg
\ No newline at end of file
diff --git a/tests/content/assets/images/og_cover.jpg b/tests/content/assets/images/og_cover.jpg
new file mode 120000
index 0000000..22ce499
--- /dev/null
+++ b/tests/content/assets/images/og_cover.jpg
@@ -0,0 +1 @@
+cover.jpg
\ No newline at end of file
diff --git a/tests/content/assets/images/page_cover.jpg b/tests/content/assets/images/page_cover.jpg
new file mode 120000
index 0000000..22ce499
--- /dev/null
+++ b/tests/content/assets/images/page_cover.jpg
@@ -0,0 +1 @@
+cover.jpg
\ No newline at end of file
diff --git a/tests/content/assets/images/raj_author_cover.jpg b/tests/content/assets/images/raj_author_cover.jpg
new file mode 120000
index 0000000..22ce499
--- /dev/null
+++ b/tests/content/assets/images/raj_author_cover.jpg
@@ -0,0 +1 @@
+cover.jpg
\ No newline at end of file
diff --git a/tests/content/assets/robots.txt b/tests/content/assets/robots.txt
new file mode 100644
index 0000000..e69de29
diff --git a/tests/content/pages/page_with_cover_image.rst b/tests/content/pages/page_with_cover_image.rst
new file mode 100644
index 0000000..5e24538
--- /dev/null
+++ b/tests/content/pages/page_with_cover_image.rst
@@ -0,0 +1,7 @@
+:title: Page With Cover Images
+:date: 2018-04-29 00:45
+:author: arul
+:category: foo
+:tags: footag
+:slug: page-with-cover-images
+:cover: assets/images/page_cover.jpg
diff --git a/tests/content/pages/page_with_http_cover_image.rst b/tests/content/pages/page_with_http_cover_image.rst
new file mode 100644
index 0000000..7512243
--- /dev/null
+++ b/tests/content/pages/page_with_http_cover_image.rst
@@ -0,0 +1,7 @@
+:title: Page With Cover Images
+:date: 2018-04-29 00:45
+:author: arul
+:category: foo
+:tags: footag
+:slug: page-with-http-cover-images
+:cover: http://example.com/page-cover.jpg
diff --git a/tests/content/pages/page_with_og_image.rst b/tests/content/pages/page_with_og_image.rst
new file mode 100644
index 0000000..3f06ff2
--- /dev/null
+++ b/tests/content/pages/page_with_og_image.rst
@@ -0,0 +1,7 @@
+:title: Page With OG Cover Images
+:date: 2018-04-29 00:59
+:author: raj
+:category: bar
+:tags: bartag
+:slug: page-with-og-cover-images
+:og_image: assets/images/og_cover.jpg
\ No newline at end of file
diff --git a/tests/content/pages/page_without_cover_image.rst b/tests/content/pages/page_without_cover_image.rst
new file mode 100644
index 0000000..296d172
--- /dev/null
+++ b/tests/content/pages/page_without_cover_image.rst
@@ -0,0 +1,6 @@
+:title: Page Without Cover Images
+:date: 2018-04-29 00:55
+:author: arul
+:category: foo
+:tags: footag
+:slug: page-without-cover-images
diff --git a/tests/default_conf.py b/tests/default_conf.py
new file mode 100644
index 0000000..2d8bd64
--- /dev/null
+++ b/tests/default_conf.py
@@ -0,0 +1,126 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*- #
+from __future__ import unicode_literals
+
+AUTHOR = u'Zutrinken'
+SITENAME = u'Attila Demo'
+SITEURL = ''
+
+PATH = 'content'
+
+DEFAULT_DATE = 'fs'
+
+DEFAULT_DATE_FORMAT = '%d %b %Y'
+
+TIMEZONE = 'Asia/Calcutta'
+
+DEFAULT_LANG = u'en'
+
+# Feed generation is usually not desired when developing
+FEED_ALL_ATOM = None
+CATEGORY_FEED_ATOM = None
+TRANSLATION_FEED_ATOM = None
+AUTHOR_FEED_ATOM = None
+AUTHOR_FEED_RSS = None
+
+# Blogroll
+LINKS = (('Pelican', 'http://getpelican.com/'),
+ ('Python.org', 'http://python.org/'),
+ ('Jinja2', 'http://jinja.pocoo.org/'),
+ ('You can modify those links in your config file', '#'),)
+
+# Social widget
+SOCIAL = (('Facebook', 'http://facebook.com/arulraj.net'),
+ ('Twitter', 'http://twitter.com/arulrajnet')
+ )
+
+# Pagination
+DEFAULT_PAGINATION = 3
+PAGINATION_PATTERNS = (
+ (1, '{base_name}/', '{base_name}/index.html'),
+ (2, '{base_name}/page/{number}/', '{base_name}/page/{number}/index.html'),
+)
+
+# Uncomment following line if you want document-relative URLs when developing
+#RELATIVE_URLS = True
+
+STATIC_PATHS = ['assets']
+
+EXTRA_PATH_METADATA = {
+ 'assets/robots.txt': {'path': 'robots.txt'},
+ 'assets/favicon.ico': {'path': 'favicon.ico'},
+ 'assets/CNAME': {'path': 'CNAME'}
+}
+
+# Post and Pages path
+ARTICLE_URL = '{date:%Y}/{date:%m}/{slug}.html'
+ARTICLE_SAVE_AS = '{date:%Y}/{date:%m}/{slug}.html'
+PAGE_URL = 'pages/{slug}/'
+PAGE_SAVE_AS = 'pages/{slug}/index.html'
+YEAR_ARCHIVE_SAVE_AS = '{date:%Y}/index.html'
+MONTH_ARCHIVE_SAVE_AS = '{date:%Y}/{date:%m}/index.html'
+
+# Tags and Category path
+CATEGORY_URL = 'category/{slug}'
+CATEGORY_SAVE_AS = 'category/{slug}/index.html'
+CATEGORIES_SAVE_AS = 'catgegories.html'
+TAG_URL = 'tag/{slug}'
+TAG_SAVE_AS = 'tag/{slug}/index.html'
+TAGS_SAVE_AS = 'tags.html'
+
+# Author
+AUTHOR_URL = 'author/{slug}'
+AUTHOR_SAVE_AS = 'author/{slug}/index.html'
+AUTHORS_SAVE_AS = 'authors.html'
+
+### Plugins
+
+# PLUGIN_PATHS = [
+# 'pelican-plugins'
+# ]
+
+# PLUGINS = [
+# 'sitemap',
+# 'neighbors',
+# 'assets'
+# ]
+
+# Sitemap
+SITEMAP = {
+ 'format': 'xml',
+ 'priorities': {
+ 'articles': 0.5,
+ 'indexes': 0.5,
+ 'pages': 0.5
+ },
+ 'changefreqs': {
+ 'articles': 'monthly',
+ 'indexes': 'daily',
+ 'pages': 'monthly'
+ }
+}
+
+# Comments
+DISQUS_SITENAME = "attilademo"
+
+# Analytics
+GOOGLE_ANALYTICS = "UA-3546274-12"
+
+THEME = 'attila'
+
+### Theme specific settings
+
+COLOR_SCHEME_CSS = 'github.css'
+
+CSS_OVERRIDE = ['assets/css/myblog.css']
+
+# AUTHORS_BIO = {
+# "arul": {
+# "name": "Arul",
+# "cover": "assets/images/avatar.png",
+# "image": "assets/images/arul_author_cover.jpg",
+# "website": "http://blog.arulraj.net",
+# "location": "Chennai",
+# "bio": "This is the place for a small biography with max 200 characters. Well, now 100 are left. Cool, hugh?"
+# }
+# }
diff --git a/tests/support.py b/tests/support.py
new file mode 100644
index 0000000..78593a6
--- /dev/null
+++ b/tests/support.py
@@ -0,0 +1,218 @@
+# -*- coding: utf-8 -*-
+from __future__ import print_function, unicode_literals
+
+import locale
+import logging
+import os
+import re
+import subprocess
+import sys
+import unittest
+from contextlib import contextmanager
+from functools import wraps
+from logging.handlers import BufferingHandler
+from os.path import abspath, dirname, join
+from shutil import rmtree
+from tempfile import mkdtemp
+
+from six import StringIO
+
+from pelican.contents import Article
+from pelican.settings import (DEFAULT_CONFIG, read_settings)
+
+__all__ = ['get_article', 'unittest', ]
+
+
+@contextmanager
+def temporary_folder():
+ """creates a temporary folder, return it and delete it afterwards.
+
+ This allows to do something like this in tests:
+
+ >>> with temporary_folder() as d:
+ # do whatever you want
+ """
+ tempdir = mkdtemp()
+ try:
+ yield tempdir
+ finally:
+ rmtree(tempdir)
+
+
+def isplit(s, sep=None):
+ """Behaves like str.split but returns a generator instead of a list.
+
+ >>> list(isplit('\tUse the force\n')) == '\tUse the force\n'.split()
+ True
+ >>> list(isplit('\tUse the force\n')) == ['Use', 'the', 'force']
+ True
+ >>> (list(isplit('\tUse the force\n', "e"))
+ == '\tUse the force\n'.split("e"))
+ True
+ >>> list(isplit('Use the force', "e")) == 'Use the force'.split("e")
+ True
+ >>> list(isplit('Use the force', "e")) == ['Us', ' th', ' forc', '']
+ True
+
+ """
+ sep, hardsep = r'\s+' if sep is None else re.escape(sep), sep is not None
+ exp, pos, length = re.compile(sep), 0, len(s)
+ while True:
+ m = exp.search(s, pos)
+ if not m:
+ if pos < length or hardsep:
+ # ^ mimic "split()": ''.split() returns []
+ yield s[pos:]
+ break
+ start = m.start()
+ if pos < start or hardsep:
+ # ^ mimic "split()": includes trailing empty string
+ yield s[pos:start]
+ pos = m.end()
+
+
+def mute(returns_output=False):
+ """Decorate a function that prints to stdout, intercepting the output.
+ If "returns_output" is True, the function will return a generator
+ yielding the printed lines instead of the return values.
+
+ The decorator literally hijack sys.stdout during each function
+ execution, so be careful with what you apply it to.
+
+ >>> def numbers():
+ print "42"
+ print "1984"
+ ...
+ >>> numbers()
+ 42
+ 1984
+ >>> mute()(numbers)()
+ >>> list(mute(True)(numbers)())
+ ['42', '1984']
+
+ """
+
+ def decorator(func):
+
+ @wraps(func)
+ def wrapper(*args, **kwargs):
+
+ saved_stdout = sys.stdout
+ sys.stdout = StringIO()
+
+ try:
+ out = func(*args, **kwargs)
+ if returns_output:
+ out = isplit(sys.stdout.getvalue().strip())
+ finally:
+ sys.stdout = saved_stdout
+
+ return out
+
+ return wrapper
+
+ return decorator
+
+
+def get_article(title, slug, content, lang, extra_metadata=None):
+ metadata = {'slug': slug, 'title': title, 'lang': lang}
+ if extra_metadata is not None:
+ metadata.update(extra_metadata)
+ return Article(content, metadata=metadata)
+
+
+def skipIfNoExecutable(executable):
+ """Skip test if `executable` is not found
+
+ Tries to run `executable` with subprocess to make sure it's in the path,
+ and skips the tests if not found (if subprocess raises a `OSError`).
+ """
+
+ with open(os.devnull, 'w') as fnull:
+ try:
+ res = subprocess.call(executable, stdout=fnull, stderr=fnull)
+ except OSError:
+ res = None
+
+ if res is None:
+ return unittest.skip('{0} executable not found'.format(executable))
+
+ return lambda func: func
+
+
+def module_exists(module_name):
+ """Test if a module is importable."""
+
+ try:
+ __import__(module_name)
+ except ImportError:
+ return False
+ else:
+ return True
+
+
+def locale_available(locale_):
+ old_locale = locale.setlocale(locale.LC_TIME)
+
+ try:
+ locale.setlocale(locale.LC_TIME, str(locale_))
+ except locale.Error:
+ return False
+ else:
+ locale.setlocale(locale.LC_TIME, old_locale)
+ return True
+
+
+def get_settings(**kwargs):
+ """Provide tweaked setting dictionaries for testing
+
+ Set keyword arguments to override specific settings.
+ """
+ settings = DEFAULT_CONFIG.copy()
+ for key, value in kwargs.items():
+ settings[key] = value
+ return settings
+
+def get_my_settings(**kwargs):
+ PATH = abspath(dirname(__file__))
+ default_conf = join(PATH, 'default_conf.py')
+ settings = read_settings(default_conf)
+ for key, value in kwargs.items():
+ settings[key] = value
+ return settings
+
+
+class LogCountHandler(BufferingHandler):
+ """Capturing and counting logged messages."""
+
+ def __init__(self, capacity=1000):
+ logging.handlers.BufferingHandler.__init__(self, capacity)
+
+ def count_logs(self, msg=None, level=None):
+ return len([
+ l
+ for l
+ in self.buffer
+ if (msg is None or re.match(msg, l.getMessage())) and
+ (level is None or l.levelno == level)
+ ])
+
+
+class LoggedTestCase(unittest.TestCase):
+ """A test case that captures log messages."""
+
+ def setUp(self):
+ super(LoggedTestCase, self).setUp()
+ self._logcount_handler = LogCountHandler()
+ logging.getLogger().addHandler(self._logcount_handler)
+
+ def tearDown(self):
+ logging.getLogger().removeHandler(self._logcount_handler)
+ super(LoggedTestCase, self).tearDown()
+
+ def assertLogCountEqual(self, count=None, msg=None, **kwargs):
+ actual = self._logcount_handler.count_logs(msg=msg, **kwargs)
+ self.assertEqual(
+ actual, count,
+ msg='expected {} occurrences of {!r}, but found {}'.format(
+ count, msg, actual))
\ No newline at end of file
diff --git a/tests/test_coverimages.py b/tests/test_coverimages.py
new file mode 100644
index 0000000..7891345
--- /dev/null
+++ b/tests/test_coverimages.py
@@ -0,0 +1,580 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+import locale
+import os
+from bs4 import BeautifulSoup
+from codecs import open
+from shutil import copy, rmtree
+from tempfile import mkdtemp
+
+from pelican.generators import (ArticlesGenerator, Generator, PagesGenerator,
+ PelicanTemplateNotFound, StaticGenerator,
+ TemplatePagesGenerator)
+from pelican.readers import RstReader
+from pelican.writers import Writer
+from pelican.contents import (Article, Page)
+from support import (get_my_settings, unittest)
+
+CUR_DIR = os.path.dirname(__file__)
+CONTENT_DIR = os.path.join(CUR_DIR, 'content')
+OUTPUT_DIR = os.path.join(CUR_DIR, 'output')
+
+def setUpModule():
+ print("setup module")
+
+def tearDownModule():
+ print("teardown module")
+ # try:
+ # rmtree(OUTPUT_DIR)
+ # except OSError, e:
+ # print ("Error: %s - %s." % (e.filename,e.strerror))
+
+class ArticleCoverImageTest(unittest.TestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ print("setUpClass")
+
+ @classmethod
+ def tearDownClass(cls):
+ print("tearDownClass")
+
+ def setUp(self):
+ self.old_locale = locale.setlocale(locale.LC_ALL)
+ locale.setlocale(locale.LC_ALL, str('C'))
+ self.settings = get_my_settings()
+ self.settings['THEME'] = "../"
+ self.settings['filenames'] = {}
+ self.reader = RstReader(self.settings)
+ self.writer = Writer("output", self.settings)
+
+ def tearDown(self):
+ locale.setlocale(locale.LC_ALL, self.old_locale)
+
+ def _gen_article_and_html_from_rst(self, rstPath):
+ content, metadata = self.reader.read(rstPath)
+ article = Article(content=content, metadata=metadata)
+ generator = ArticlesGenerator( context=self.settings.copy(), settings=self.settings, path=CONTENT_DIR, theme=self.settings['THEME'], output_path=OUTPUT_DIR)
+ generator.generate_context()
+ f = lambda a: True if (a.slug == article.slug) else False
+ result = filter(f, generator.context["articles"])[0]
+ self.writer.write_file(
+ result.save_as, generator.get_template('article'),
+ generator.context, article=result)
+ soup = BeautifulSoup(open("./"+self.writer.output_path+'/'+result.save_as), "html.parser")
+ return (result, soup)
+
+ def test_article_cover(self):
+ self.settings['SITEURL']="http://www.example.com"
+ rstPath="content/article_with_cover_image.rst"
+ result, soup = self._gen_article_and_html_from_rst(rstPath)
+ selected = soup.find(name="div", attrs={"class": "post-cover cover"})
+ # Assertion
+ self.assertTrue(self.settings['SITEURL']+'/'+result.cover in selected["style"])
+
+ def test_article_header_cover(self):
+ self.settings['HEADER_COVER']='/assets/images/header_cover.jpg'
+ rstPath="content/article_without_cover.rst"
+ result, soup = self._gen_article_and_html_from_rst(rstPath)
+ selected = soup.find(name="div", attrs={"class": "post-cover cover"})
+ # Assertion
+ self.assertTrue(self.settings['SITEURL']+'/'+self.settings['HEADER_COVER'] in selected["style"])
+
+ def test_article_header_http_cover(self):
+ self.settings['HEADER_COVER']='http://example.com/cover.jpg'
+ rstPath="content/article_without_cover.rst"
+ result, soup = self._gen_article_and_html_from_rst(rstPath)
+ selected = soup.find(name="div", attrs={"class": "post-cover cover"})
+ # Assertion
+ self.assertTrue(self.settings['HEADER_COVER'] in selected["style"])
+
+ def test_article_theme_cover(self):
+ rstPath="content/article_without_cover.rst"
+ result, soup = self._gen_article_and_html_from_rst(rstPath)
+ selected = soup.find(name="div", attrs={"class": "post-cover cover"})
+ # Assertion
+ self.assertTrue("/theme/images/post-bg.jpg" in selected["style"])
+
+ def test_article_header_color(self):
+ self.settings['HEADER_COLOR']='blue'
+ rstPath="content/article_without_cover.rst"
+ result, soup = self._gen_article_and_html_from_rst(rstPath)
+ selected = soup.find(name="div", attrs={"class": "post-cover cover"})
+ # Assertion
+ self.assertTrue(self.settings['HEADER_COLOR'] in selected["style"])
+
+ def test_article_http_cover(self):
+ rstPath="content/article_with_http_cover_image.rst"
+ result, soup = self._gen_article_and_html_from_rst(rstPath)
+ selected = soup.find(name="div", attrs={"class": "post-cover cover"})
+ # Assertion
+ self.assertTrue(result.cover in selected["style"])
+
+ def test_article_og_cover(self):
+ rstPath="content/article_with_og_image.rst"
+ result, soup = self._gen_article_and_html_from_rst(rstPath)
+ selected = soup.find(name="div", attrs={"class": "post-cover cover"})
+ # Assertion
+ self.assertTrue(result.og_image in selected["style"])
+
+class PageCoverImageTest(unittest.TestCase):
+
+ def setUp(self):
+ self.old_locale = locale.setlocale(locale.LC_ALL)
+ locale.setlocale(locale.LC_ALL, str('C'))
+ self.settings = get_my_settings()
+ self.settings['THEME'] = "../"
+ self.settings['filenames'] = {}
+ self.reader = RstReader(self.settings)
+ self.writer = Writer("output", self.settings)
+
+ def tearDown(self):
+ locale.setlocale(locale.LC_ALL, self.old_locale)
+
+ def _gen_page_and_html_from_rst(self, rstPath):
+ content, metadata = self.reader.read(rstPath)
+ page = Page(content=content, metadata=metadata)
+ generator = PagesGenerator( context=self.settings.copy(), settings=self.settings, path=CONTENT_DIR, theme=self.settings['THEME'], output_path=OUTPUT_DIR)
+ generator.generate_context()
+ f = lambda a: True if (a.slug == page.slug) else False
+ result = filter(f, generator.context["pages"])[0]
+ self.writer.write_file(
+ result.save_as, generator.get_template('page'),
+ generator.context, page=result)
+ soup = BeautifulSoup(open("./"+self.writer.output_path+'/'+result.save_as), "html.parser")
+ return (result, soup)
+
+ def test_page_cover(self):
+ self.settings['SITEURL']="http://www.example.com"
+ rstPath="content/pages/page_with_cover_image.rst"
+ result, soup = self._gen_page_and_html_from_rst(rstPath)
+ selected = soup.find(name="div", attrs={"class": "post-cover cover"})
+ # Assertion
+ self.assertTrue(self.settings['SITEURL']+'/'+result.cover in selected["style"])
+
+ def test_page_header_cover(self):
+ self.settings['HEADER_COVER']='/assets/images/header_cover.jpg'
+ rstPath="content/pages/page_without_cover_image.rst"
+ result, soup = self._gen_page_and_html_from_rst(rstPath)
+ selected = soup.find(name="div", attrs={"class": "post-cover cover"})
+ # Assertion
+ self.assertTrue(self.settings['SITEURL']+'/'+self.settings['HEADER_COVER'] in selected["style"])
+
+ def test_page_header_http_cover(self):
+ self.settings['HEADER_COVER']='http://example.com/cover.jpg'
+ rstPath="content/pages/page_without_cover_image.rst"
+ result, soup = self._gen_page_and_html_from_rst(rstPath)
+ selected = soup.find(name="div", attrs={"class": "post-cover cover"})
+ # Assertion
+ self.assertTrue(self.settings['HEADER_COVER'] in selected["style"])
+
+ def test_page_theme_cover(self):
+ rstPath="content/pages/page_without_cover_image.rst"
+ result, soup = self._gen_page_and_html_from_rst(rstPath)
+ selected = soup.find(name="div", attrs={"class": "post-cover cover"})
+ # Assertion
+ self.assertTrue("/theme/images/post-bg.jpg" in selected["style"])
+
+ def test_page_header_color(self):
+ self.settings['HEADER_COLOR']='blue'
+ rstPath="content/pages/page_without_cover_image.rst"
+ result, soup = self._gen_page_and_html_from_rst(rstPath)
+ selected = soup.find(name="div", attrs={"class": "post-cover cover"})
+ # Assertion
+ self.assertTrue(self.settings['HEADER_COLOR'] in selected["style"])
+
+ def test_page_http_cover(self):
+ rstPath="content/pages/page_with_http_cover_image.rst"
+ result, soup = self._gen_page_and_html_from_rst(rstPath)
+ selected = soup.find(name="div", attrs={"class": "post-cover cover"})
+ # Assertion
+ self.assertTrue(result.cover in selected["style"])
+
+ def test_page_og_cover(self):
+ rstPath="content/pages/page_with_og_image.rst"
+ result, soup = self._gen_page_and_html_from_rst(rstPath)
+ selected = soup.find(name="div", attrs={"class": "post-cover cover"})
+ # Assertion
+ self.assertTrue(result.og_image in selected["style"])
+
+class TagCoverImageTest(unittest.TestCase):
+
+ def setUp(self):
+ self.old_locale = locale.setlocale(locale.LC_ALL)
+ locale.setlocale(locale.LC_ALL, str('C'))
+ self.settings = get_my_settings()
+ self.settings['THEME'] = "../"
+ self.settings['filenames'] = {}
+ self.reader = RstReader(self.settings)
+ self.writer = Writer("output", self.settings)
+
+ def _gen_tag_and_html_from_name(self, name):
+ generator = ArticlesGenerator( context=self.settings.copy(), settings=self.settings, path=CONTENT_DIR, theme=self.settings['THEME'], output_path=OUTPUT_DIR)
+ generator.generate_context()
+ generator.generate_tags(self.writer.write_file)
+ selectedTag = None
+
+ for tag, articles in generator.tags.items():
+ if tag.name == name:
+ selectedTag = tag
+
+ soup = BeautifulSoup(open("./"+self.writer.output_path+'/'+selectedTag.save_as), "html.parser")
+ return (selectedTag, soup)
+
+ def tearDown(self):
+ locale.setlocale(locale.LC_ALL, self.old_locale)
+
+ def test_footag_theme_cover(self):
+ result, soup = self._gen_tag_and_html_from_name("footag")
+ selected = soup.find(name="div", attrs={"class": "blog-cover cover"})
+ # Assertion
+ self.assertTrue("/theme/images/post-bg.jpg" in selected["style"])
+
+ def test_footag_cover(self):
+ tagName = "footag"
+ self.settings['HEADER_COVERS_BY_TAG'] = {
+ tagName: "/assets/images/foo_tag_cover.jpg"
+ }
+ result, soup = self._gen_tag_and_html_from_name(tagName)
+ selected = soup.find(name="div", attrs={"class": "blog-cover cover"})
+ # Assertion
+ self.assertTrue(self.settings['SITEURL']+'/'+self.settings['HEADER_COVERS_BY_TAG'][tagName] in selected["style"])
+
+ def test_footag_http_cover(self):
+ tagName = "footag"
+ self.settings['HEADER_COVERS_BY_TAG'] = {
+ tagName: "http://examble.com/cover.jpg"
+ }
+ result, soup = self._gen_tag_and_html_from_name(tagName)
+ selected = soup.find(name="div", attrs={"class": "blog-cover cover"})
+ # Assertion
+ self.assertTrue(self.settings['HEADER_COVERS_BY_TAG'][tagName] in selected["style"])
+
+ def test_footag_header_cover(self):
+ self.settings['SITEURL'] = "http://example.com"
+ self.settings["HEADER_COVER"] = "/assets/images/header_cover.jpg"
+ result, soup = self._gen_tag_and_html_from_name("footag")
+ selected = soup.find(name="div", attrs={"class": "blog-cover cover"})
+ # Assertion
+ self.assertTrue(self.settings['SITEURL']+'/'+self.settings["HEADER_COVER"] in selected["style"])
+
+ def test_footag_header_http_cover(self):
+ self.settings["HEADER_COVER"] = "http://example.com/cover.jpg"
+ result, soup = self._gen_tag_and_html_from_name("footag")
+ selected = soup.find(name="div", attrs={"class": "blog-cover cover"})
+ # Assertion
+ self.assertTrue(self.settings["HEADER_COVER"] in selected["style"])
+
+ def test_footag_header_color(self):
+ self.settings["HEADER_COLOR"] = "red"
+ result, soup = self._gen_tag_and_html_from_name("footag")
+ selected = soup.find(name="div", attrs={"class": "blog-cover cover"})
+ # Assertion
+ self.assertTrue(self.settings["HEADER_COLOR"] in selected["style"])
+
+ def test_bartag_theme_cover(self):
+ result, soup = self._gen_tag_and_html_from_name("bartag")
+ selected = soup.find(name="div", attrs={"class": "blog-cover cover"})
+ # Assertion
+ self.assertTrue("/theme/images/post-bg.jpg" in selected["style"])
+
+ def test_bartag_cover(self):
+ tagName = "bartag"
+ self.settings['HEADER_COVERS_BY_TAG'] = {
+ tagName: "/assets/images/bar_tag_cover.jpg"
+ }
+ result, soup = self._gen_tag_and_html_from_name(tagName)
+ selected = soup.find(name="div", attrs={"class": "blog-cover cover"})
+ # Assertion
+ self.assertTrue(self.settings['SITEURL']+'/'+self.settings['HEADER_COVERS_BY_TAG'][tagName] in selected["style"])
+
+ def test_bartag_http_cover(self):
+ tagName = "bartag"
+ self.settings['HEADER_COVERS_BY_TAG'] = {
+ tagName: "http://examble.com/cover.jpg"
+ }
+ result, soup = self._gen_tag_and_html_from_name(tagName)
+ selected = soup.find(name="div", attrs={"class": "blog-cover cover"})
+ # Assertion
+ self.assertTrue(self.settings['HEADER_COVERS_BY_TAG'][tagName] in selected["style"])
+
+ def test_bartag_header_cover(self):
+ self.settings['SITEURL'] = "http://example.com"
+ self.settings["HEADER_COVER"] = "/assets/images/header_cover.jpg"
+ result, soup = self._gen_tag_and_html_from_name("bartag")
+ selected = soup.find(name="div", attrs={"class": "blog-cover cover"})
+ # Assertion
+ self.assertTrue(self.settings['SITEURL']+'/'+self.settings["HEADER_COVER"] in selected["style"])
+
+ def test_bartag_header_http_cover(self):
+ self.settings["HEADER_COVER"] = "http://example.com/cover.jpg"
+ result, soup = self._gen_tag_and_html_from_name("bartag")
+ selected = soup.find(name="div", attrs={"class": "blog-cover cover"})
+ # Assertion
+ self.assertTrue(self.settings["HEADER_COVER"] in selected["style"])
+
+ def test_bartag_header_color(self):
+ self.settings["HEADER_COLOR"] = "red"
+ result, soup = self._gen_tag_and_html_from_name("bartag")
+ selected = soup.find(name="div", attrs={"class": "blog-cover cover"})
+ # Assertion
+ self.assertTrue(self.settings["HEADER_COLOR"] in selected["style"])
+
+
+class CategoryCoverImageTest(unittest.TestCase):
+
+ def setUp(self):
+ self.old_locale = locale.setlocale(locale.LC_ALL)
+ locale.setlocale(locale.LC_ALL, str('C'))
+ self.settings = get_my_settings()
+ self.settings['THEME'] = "../"
+ self.settings['filenames'] = {}
+ self.reader = RstReader(self.settings)
+ self.writer = Writer("output", self.settings)
+
+ def tearDown(self):
+ locale.setlocale(locale.LC_ALL, self.old_locale)
+
+ def _gen_category_and_html_from_name(self, name):
+ generator = ArticlesGenerator( context=self.settings.copy(), settings=self.settings, path=CONTENT_DIR, theme=self.settings['THEME'], output_path=OUTPUT_DIR)
+ generator.generate_context()
+ generator.generate_categories(self.writer.write_file)
+ selectedCategory = None
+
+ for category, articles in generator.categories:
+ if category.name == name:
+ selectedCategory = category
+
+ soup = BeautifulSoup(open("./"+self.writer.output_path+'/'+selectedCategory.save_as), "html.parser")
+ return (selectedCategory, soup)
+
+ def test_foo_theme_cover(self):
+ result, soup = self._gen_category_and_html_from_name("foo")
+ selected = soup.find(name="div", attrs={"class": "blog-cover cover"})
+ # Assertion
+ self.assertTrue("/theme/images/post-bg.jpg" in selected["style"])
+
+ def test_foo_cover(self):
+ categoryName = "foo"
+ self.settings['HEADER_COVERS_BY_CATEGORY'] = {
+ categoryName: "/assets/images/foo_category_cover.jpg"
+ }
+ result, soup = self._gen_category_and_html_from_name(categoryName)
+ selected = soup.find(name="div", attrs={"class": "blog-cover cover"})
+ # Assertion
+ self.assertTrue(self.settings['SITEURL']+'/'+self.settings['HEADER_COVERS_BY_CATEGORY'][categoryName] in selected["style"])
+
+ def test_foo_http_cover(self):
+ categoryName = "foo"
+ self.settings['HEADER_COVERS_BY_CATEGORY'] = {
+ categoryName: "http://examble.com/cover.jpg"
+ }
+ result, soup = self._gen_category_and_html_from_name(categoryName)
+ selected = soup.find(name="div", attrs={"class": "blog-cover cover"})
+ # Assertion
+ self.assertTrue(self.settings['HEADER_COVERS_BY_CATEGORY'][categoryName] in selected["style"])
+
+ def test_foo_header_cover(self):
+ self.settings['SITEURL'] = "http://example.com"
+ self.settings["HEADER_COVER"] = "/assets/images/header_cover.jpg"
+ result, soup = self._gen_category_and_html_from_name("foo")
+ selected = soup.find(name="div", attrs={"class": "blog-cover cover"})
+ # Assertion
+ self.assertTrue(self.settings['SITEURL']+'/'+self.settings["HEADER_COVER"] in selected["style"])
+
+ def test_foo_header_http_cover(self):
+ self.settings["HEADER_COVER"] = "http://example.com/cover.jpg"
+ result, soup = self._gen_category_and_html_from_name("foo")
+ selected = soup.find(name="div", attrs={"class": "blog-cover cover"})
+ # Assertion
+ self.assertTrue(self.settings["HEADER_COVER"] in selected["style"])
+
+ def test_foo_header_color(self):
+ self.settings["HEADER_COLOR"] = "red"
+ result, soup = self._gen_category_and_html_from_name("foo")
+ selected = soup.find(name="div", attrs={"class": "blog-cover cover"})
+ # Assertion
+ self.assertTrue(self.settings["HEADER_COLOR"] in selected["style"])
+
+ def test_bar_theme_cover(self):
+ result, soup = self._gen_category_and_html_from_name("bar")
+ selected = soup.find(name="div", attrs={"class": "blog-cover cover"})
+ # Assertion
+ self.assertTrue("/theme/images/post-bg.jpg" in selected["style"])
+
+ def test_bar_cover(self):
+ categoryName = "bar"
+ self.settings['HEADER_COVERS_BY_CATEGORY'] = {
+ categoryName: "/assets/images/bar_category_cover.jpg"
+ }
+ result, soup = self._gen_category_and_html_from_name(categoryName)
+ selected = soup.find(name="div", attrs={"class": "blog-cover cover"})
+ # Assertion
+ self.assertTrue(self.settings['SITEURL']+'/'+self.settings['HEADER_COVERS_BY_CATEGORY'][categoryName] in selected["style"])
+
+ def test_bar_http_cover(self):
+ categoryName = "bar"
+ self.settings['HEADER_COVERS_BY_CATEGORY'] = {
+ categoryName: "http://examble.com/cover.jpg"
+ }
+ result, soup = self._gen_category_and_html_from_name(categoryName)
+ selected = soup.find(name="div", attrs={"class": "blog-cover cover"})
+ # Assertion
+ self.assertTrue(self.settings['HEADER_COVERS_BY_CATEGORY'][categoryName] in selected["style"])
+
+ def test_bar_header_cover(self):
+ self.settings['SITEURL'] = "http://example.com"
+ self.settings["HEADER_COVER"] = "/assets/images/header_cover.jpg"
+ result, soup = self._gen_category_and_html_from_name("bar")
+ selected = soup.find(name="div", attrs={"class": "blog-cover cover"})
+ # Assertion
+ self.assertTrue(self.settings['SITEURL']+'/'+self.settings["HEADER_COVER"] in selected["style"])
+
+ def test_bar_header_http_cover(self):
+ self.settings["HEADER_COVER"] = "http://example.com/cover.jpg"
+ result, soup = self._gen_category_and_html_from_name("bar")
+ selected = soup.find(name="div", attrs={"class": "blog-cover cover"})
+ # Assertion
+ self.assertTrue(self.settings["HEADER_COVER"] in selected["style"])
+
+ def test_bar_header_color(self):
+ self.settings["HEADER_COLOR"] = "red"
+ result, soup = self._gen_category_and_html_from_name("bar")
+ selected = soup.find(name="div", attrs={"class": "blog-cover cover"})
+ # Assertion
+ self.assertTrue(self.settings["HEADER_COLOR"] in selected["style"])
+
+class AuthorCoverImageTest(unittest.TestCase):
+
+ def setUp(self):
+ self.old_locale = locale.setlocale(locale.LC_ALL)
+ locale.setlocale(locale.LC_ALL, str('C'))
+ self.settings = get_my_settings()
+ self.settings['THEME'] = "../"
+ self.settings['filenames'] = {}
+ self.reader = RstReader(self.settings)
+ self.writer = Writer("output", self.settings)
+
+ def tearDown(self):
+ locale.setlocale(locale.LC_ALL, self.old_locale)
+
+ def _gen_author_and_html_from_name(self, name):
+ generator = ArticlesGenerator( context=self.settings.copy(), settings=self.settings, path=CONTENT_DIR, theme=self.settings['THEME'], output_path=OUTPUT_DIR)
+ generator.generate_context()
+ generator.generate_authors(self.writer.write_file)
+ selectedAuthor = None
+
+ for author, articles in generator.authors:
+ if author.name == name:
+ selectedAuthor = author
+
+ soup = BeautifulSoup(open("./"+self.writer.output_path+'/'+selectedAuthor.save_as), "html.parser")
+ return (selectedAuthor, soup)
+
+ def test_arul_theme_cover(self):
+ result, soup = self._gen_author_and_html_from_name("arul")
+ selected = soup.find(name="div", attrs={"class": "blog-cover cover"})
+ # Assertion
+ self.assertTrue("/theme/images/post-bg.jpg" in selected["style"])
+
+ def test_arul_cover(self):
+ authorName = "arul"
+ self.settings['AUTHORS_BIO'] = {
+ authorName: {
+ 'cover': "/assets/images/arul_author_cover.jpg"
+ }
+ }
+ result, soup = self._gen_author_and_html_from_name(authorName)
+ selected = soup.find(name="div", attrs={"class": "blog-cover cover"})
+ # Assertion
+ self.assertTrue(self.settings['SITEURL']+'/'+self.settings['AUTHORS_BIO'][authorName]['cover'] in selected["style"])
+
+ def test_arul_http_cover(self):
+ authorName = "arul"
+ self.settings['AUTHORS_BIO'] = {
+ authorName: {
+ 'cover': "http://examble.com/cover.jpg"
+ }
+ }
+ result, soup = self._gen_author_and_html_from_name(authorName)
+ selected = soup.find(name="div", attrs={"class": "blog-cover cover"})
+ # Assertion
+ self.assertTrue(self.settings['AUTHORS_BIO'][authorName]['cover'] in selected["style"])
+
+ def test_arul_header_cover(self):
+ self.settings['SITEURL'] = "http://example.com"
+ self.settings["HEADER_COVER"] = "/assets/images/header_cover.jpg"
+ result, soup = self._gen_author_and_html_from_name("arul")
+ selected = soup.find(name="div", attrs={"class": "blog-cover cover"})
+ # Assertion
+ self.assertTrue(self.settings['SITEURL']+'/'+self.settings["HEADER_COVER"] in selected["style"])
+
+ def test_arul_header_http_cover(self):
+ self.settings["HEADER_COVER"] = "http://example.com/cover.jpg"
+ result, soup = self._gen_author_and_html_from_name("arul")
+ selected = soup.find(name="div", attrs={"class": "blog-cover cover"})
+ # Assertion
+ self.assertTrue(self.settings["HEADER_COVER"] in selected["style"])
+
+ def test_arul_header_color(self):
+ self.settings["HEADER_COLOR"] = "red"
+ result, soup = self._gen_author_and_html_from_name("arul")
+ selected = soup.find(name="div", attrs={"class": "blog-cover cover"})
+ # Assertion
+ self.assertTrue(self.settings["HEADER_COLOR"] in selected["style"])
+
+ def test_raj_theme_cover(self):
+ result, soup = self._gen_author_and_html_from_name("raj")
+ selected = soup.find(name="div", attrs={"class": "blog-cover cover"})
+ # Assertion
+ self.assertTrue("/theme/images/post-bg.jpg" in selected["style"])
+
+ def test_raj_cover(self):
+ authorName = "raj"
+ self.settings['AUTHORS_BIO'] = {
+ authorName: {
+ 'cover': "/assets/images/raj_author_cover.jpg"
+ }
+ }
+ result, soup = self._gen_author_and_html_from_name(authorName)
+ selected = soup.find(name="div", attrs={"class": "blog-cover cover"})
+ # Assertion
+ self.assertTrue(self.settings['SITEURL']+'/'+self.settings['AUTHORS_BIO'][authorName]['cover'] in selected["style"])
+
+ def test_raj_http_cover(self):
+ authorName = "raj"
+ self.settings['AUTHORS_BIO'] = {
+ authorName: {
+ 'cover': "http://examble.com/cover.jpg"
+ }
+ }
+ result, soup = self._gen_author_and_html_from_name(authorName)
+ selected = soup.find(name="div", attrs={"class": "blog-cover cover"})
+ # Assertion
+ self.assertTrue(self.settings['AUTHORS_BIO'][authorName]['cover'] in selected["style"])
+
+ def test_raj_header_cover(self):
+ self.settings['SITEURL'] = "http://example.com"
+ self.settings["HEADER_COVER"] = "/assets/images/header_cover.jpg"
+ result, soup = self._gen_author_and_html_from_name("raj")
+ selected = soup.find(name="div", attrs={"class": "blog-cover cover"})
+ # Assertion
+ self.assertTrue(self.settings['SITEURL']+'/'+self.settings["HEADER_COVER"] in selected["style"])
+
+ def test_raj_header_http_cover(self):
+ self.settings["HEADER_COVER"] = "http://example.com/cover.jpg"
+ result, soup = self._gen_author_and_html_from_name("raj")
+ selected = soup.find(name="div", attrs={"class": "blog-cover cover"})
+ # Assertion
+ self.assertTrue(self.settings["HEADER_COVER"] in selected["style"])
+
+ def test_raj_header_color(self):
+ self.settings["HEADER_COLOR"] = "red"
+ result, soup = self._gen_author_and_html_from_name("raj")
+ selected = soup.find(name="div", attrs={"class": "blog-cover cover"})
+ # Assertion
+ self.assertTrue(self.settings["HEADER_COLOR"] in selected["style"])
+
+if __name__ == '__main__':
+ unittest.main()
\ No newline at end of file
diff --git a/tests/unittest.cfg b/tests/unittest.cfg
new file mode 100644
index 0000000..9aa593f
--- /dev/null
+++ b/tests/unittest.cfg
@@ -0,0 +1,3 @@
+[debugger]
+always-on = True
+errors-only = False
\ No newline at end of file