diff --git a/incorporealcms/__init__.py b/incorporealcms/__init__.py
index 7b50bb3..45ceb25 100644
--- a/incorporealcms/__init__.py
+++ b/incorporealcms/__init__.py
@@ -1,4 +1,4 @@
-"""create_app application factory function and similar things."""
+"""An application for running my Markdown-based sites."""
import logging
import os
from logging.config import dictConfig
@@ -12,6 +12,7 @@ del get_versions
def create_app(instance_path=None, test_config=None):
+ """Create the Flask app, with allowances for customizing path and test settings."""
app = Flask(__name__, instance_relative_config=True, instance_path=instance_path)
# if it doesn't already exist, create the instance folder
diff --git a/tests/conftest.py b/tests/conftest.py
index b24d937..5967d31 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -10,6 +10,7 @@ HERE = os.path.dirname(os.path.abspath(__file__))
@pytest.fixture
def app():
+ """Create the Flask application, with test settings."""
app = create_app(instance_path=os.path.join(HERE, 'instance'))
yield app
@@ -17,4 +18,5 @@ def app():
@pytest.fixture
def client(app):
+ """Create a test client based on the test app."""
return app.test_client()
diff --git a/tests/instance/config.py b/tests/instance/config.py
index a704cea..4a0c0de 100644
--- a/tests/instance/config.py
+++ b/tests/instance/config.py
@@ -1,3 +1,5 @@
+"""Configure the test application."""
+
LOGGING = {
'version': 1,
'formatters': {
diff --git a/tests/test_factory.py b/tests/test_factory.py
index 2acf780..06177a8 100644
--- a/tests/test_factory.py
+++ b/tests/test_factory.py
@@ -24,6 +24,7 @@ def test_title_override():
def test_media_file_access(client):
+ """Test that media files are served, and properly."""
response = client.get('/media/favicon.png')
assert response.status_code == 200
assert response.headers['content-type'] == 'image/png'
diff --git a/tests/test_pages.py b/tests/test_pages.py
index 8ab4158..7fe7c5b 100644
--- a/tests/test_pages.py
+++ b/tests/test_pages.py
@@ -5,35 +5,42 @@ from incorporealcms.pages import generate_parent_navs, resolve_page_file
def test_resolve_page_file_dir_to_index():
+ """Test that a request to a directory path results in the dir's index.md."""
assert resolve_page_file('foo/') == 'pages/foo/index.md'
def test_resolve_page_file_subdir_to_index():
+ """Test that a request to a dir's subdir path results in the subdir's index.md."""
assert resolve_page_file('foo/bar/') == 'pages/foo/bar/index.md'
def test_resolve_page_file_other_requests_fine():
+ """Test that a request to non-dir path results in a Markdown file."""
assert resolve_page_file('foo/baz') == 'pages/foo/baz.md'
def test_page_that_exists(client):
+ """Test that the app can serve a basic file at the index."""
response = client.get('/')
assert response.status_code == 200
assert b'
test index
' in response.data
def test_page_that_doesnt_exist(client):
+ """Test that the app returns 404 for nonsense requests."""
response = client.get('/ohuesthaoeusth')
assert response.status_code == 404
def test_page_with_title_metadata(client):
+ """Test that a page with title metadata has its title written."""
response = client.get('/')
assert response.status_code == 200
assert b'Index - incorporeal.org' in response.data
def test_page_without_title_metadata(client):
+ """Test that a page without title metadata gets the default title."""
response = client.get('/no-title')
assert response.status_code == 200
assert b'incorporeal.org' in response.data
@@ -41,33 +48,39 @@ def test_page_without_title_metadata(client):
def test_page_has_modified_timestamp(client):
+ """Test that pages have modified timestamps in them."""
response = client.get('/')
assert response.status_code == 200
assert re.search(r'Last modified: ....-..-.. ..:..:.. ...', response.data.decode()) is not None
def test_generate_page_navs_index(app):
+ """Test that the index page has navs to the root (itself)."""
with app.app_context():
assert generate_parent_navs('/') == [('incorporeal.org', '/')]
def test_generate_page_navs_alternate_index(app):
+ """Test that the index page (as a page, not a path) also has navs only to the root (by path)."""
with app.app_context():
assert generate_parent_navs('index') == [('incorporeal.org', '/')]
def test_generate_page_navs_subdir_index(app):
+ """Test that dir pages have navs to the root and themselves."""
with app.app_context():
assert generate_parent_navs('subdir/') == [('incorporeal.org', '/'), ('/subdir/', '/subdir/')]
def test_generate_page_navs_subdir_real_page(app):
+ """Test that real pages have navs to the root, their parent, and themselves."""
with app.app_context():
assert generate_parent_navs('subdir/page') == [('incorporeal.org', '/'), ('/subdir/', '/subdir/'),
('Page', '/subdir/page')]
def test_generate_page_navs_subdir_with_title_parsing_real_page(app):
+ """Test that title metadata is used in the nav text."""
with app.app_context():
assert generate_parent_navs('subdir-with-title/page') == [
('incorporeal.org', '/'),
diff --git a/tox.ini b/tox.ini
index 63335f3..c5eec13 100644
--- a/tox.ini
+++ b/tox.ini
@@ -4,7 +4,7 @@
# and then run "tox" from this directory.
[tox]
-envlist = py37,artifacts
+envlist = py37,lint
[testenv]
# build a wheel and test it
@@ -13,6 +13,7 @@ wheel_build_env = build
deps =
flake8
+ flake8-docstrings
pytest
pytest-cov
commands =
@@ -26,20 +27,38 @@ whitelist_externals = ln
# require setuptools when building
deps = setuptools
-[testenv:artifacts]
+[testenv:py37]
+# run pytest and coverage
deps =
-skip_install = true
+ coverage
+ pytest
+ pytest-cov
commands =
+ pytest --cov={envsitepackagesdir}/incorporealcms/ --cov-report=
+ coverage report -m --fail-under=80
ln -sf {distdir} dist
+[testenv:lint]
+# run style checks
+skip_install = true
+deps =
+ flake8
+ flake8-docstrings
+commands =
+ flake8
+ - flake8 --disable-noqa --select=E,W,F,C,D
+
[flake8]
max-line-length = 120
-exclude = .tox/,versioneer.py,_version.py
-max-complexity = 5
+exclude =
+ .tox/
+ versioneer.py
+ _version.py
+ instance/
+max-complexity = 10
[pytest]
python_files = tests.py test_*.py
-addopts = --cov-report=term --cov-report=term-missing
[coverage:run]
branch = True