Skip to content

Commit d670dd1

Browse files
committed
Added more unit tests based on the existing examples
Also: - Renamed test_simple_object.py to test_simple.py - Added .appveyor.yml in preparation for Windows testing - Added .travis.yml in preparation for Linux testing - Added .coveragerc for code coverage analysis - Added tasks.py for using invoke to automate common tasks such as running unit tests with code coverage
1 parent 69cc9b2 commit d670dd1

File tree

6 files changed

+399
-48
lines changed

6 files changed

+399
-48
lines changed

.appveyor.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
install:
2+
- python -m pip install tox
3+
4+
build: off
5+
6+
test_script:
7+
- python -m tox -e py35-win,py36-win

.coveragerc

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# .coveragerc to control coverage.py
2+
[run]
3+
# Source
4+
source = tableformatter.py
5+
# (boolean, default False): whether to measure branch coverage in addition to statement coverage.
6+
branch = False
7+
8+
9+
[report]
10+
# A list of regular expressions. Any line that matches one of these regexes is excluded from being reported as missing
11+
exclude_lines =
12+
# Have to re-enable the standard pragma
13+
pragma: no cover
14+
15+
# Don't complain if non-runnable code isn't run:
16+
if __name__ == .__main__.:
17+
18+
# (integer): the number of digits after the decimal point to display for reported coverage percentages.
19+
precision = 1
20+
21+
22+
[html]
23+
# (string, default “htmlcov”): where to write the HTML report files.
24+
directory = htmlcov

.travis.yml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
language: python
2+
3+
sudo: false # false enables container-based build for fast boot times on Linux
4+
5+
matrix:
6+
include:
7+
- os: linux
8+
python: 3.4
9+
env: TOXENV=py34
10+
- os: linux
11+
python: 3.5
12+
env: TOXENV=py35
13+
- os: linux
14+
python: 3.6
15+
env: TOXENV=py36
16+
- os: linux
17+
python: 3.7-dev
18+
env: TOXENV=py37
19+
# # Warning: Don't try to use code coverage analysis with pypy as it is insanely slow
20+
# - os: linux
21+
# python: pypy3
22+
# env: TOXENV=pypy3
23+
# # Latest Python 3.x from Homebrew
24+
# - os: osx
25+
# language: generic
26+
# env:
27+
# - TOXENV=py36
28+
# - BREW_INSTALL=python3
29+
30+
install:
31+
- pip install tox
32+
# - |
33+
# if [[ $TRAVIS_OS_NAME == 'osx' ]]; then
34+
# if [[ -n "$BREW_INSTALL" ]]; then
35+
# brew update
36+
# brew install "$BREW_INSTALL"
37+
# fi
38+
# fi
39+
# pip install tox
40+
41+
script:
42+
- tox

tasks.py

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
#
2+
# coding=utf-8
3+
"""Development related tasks to be run with 'invoke'.
4+
5+
Make sure you satisfy the following Python module requirements if you are trying to publish a release to PyPI:
6+
- twine >= 1.11.0
7+
- wheel >= 0.31.0
8+
- setuptools >= 39.1.0
9+
"""
10+
import os
11+
import shutil
12+
13+
import invoke
14+
15+
# shared function
16+
def rmrf(items, verbose=True):
17+
"Silently remove a list of directories or files"
18+
if isinstance(items, str):
19+
items = [items]
20+
21+
for item in items:
22+
if verbose:
23+
print("Removing {}".format(item))
24+
shutil.rmtree(item, ignore_errors=True)
25+
# rmtree doesn't remove bare files
26+
try:
27+
os.remove(item)
28+
except FileNotFoundError:
29+
pass
30+
31+
32+
# create namespaces
33+
namespace = invoke.Collection()
34+
namespace_clean = invoke.Collection('clean')
35+
namespace.add_collection(namespace_clean, 'clean')
36+
37+
#####
38+
#
39+
# pytest, tox, pylint, and codecov
40+
#
41+
#####
42+
@invoke.task
43+
def pytest(context):
44+
"Run tests and code coverage using pytest"
45+
context.run("pytest --cov=tableformatter --cov-report=term --cov-report=html")
46+
namespace.add_task(pytest)
47+
48+
@invoke.task
49+
def pytest_clean(context):
50+
"Remove pytest cache and code coverage files and directories"
51+
#pylint: disable=unused-argument
52+
dirs = ['.pytest_cache', '.cache', 'htmlcov', '.coverage']
53+
rmrf(dirs)
54+
namespace_clean.add_task(pytest_clean, 'pytest')
55+
56+
@invoke.task
57+
def mypy(context):
58+
"Run mypy optional static type checker"
59+
context.run("mypy main.py")
60+
namespace.add_task(mypy)
61+
namespace.add_task(mypy)
62+
63+
@invoke.task
64+
def mypy_clean(context):
65+
"Remove mypy cache directory"
66+
#pylint: disable=unused-argument
67+
dirs = ['.mypy_cache']
68+
rmrf(dirs)
69+
namespace_clean.add_task(mypy_clean, 'mypy')
70+
71+
@invoke.task
72+
def tox(context):
73+
"Run unit and integration tests on multiple python versions using tox"
74+
context.run("tox")
75+
namespace.add_task(tox)
76+
77+
@invoke.task
78+
def tox_clean(context):
79+
"Remove tox virtualenvs and logs"
80+
#pylint: disable=unused-argument
81+
rmrf('.tox')
82+
namespace_clean.add_task(tox_clean, 'tox')
83+
84+
85+
#####
86+
#
87+
# documentation
88+
#
89+
#####
90+
DOCS_SRCDIR = 'docs'
91+
DOCS_BUILDDIR = os.path.join('docs', '_build')
92+
93+
@invoke.task()
94+
def docs(context, builder='html'):
95+
"Build documentation using sphinx"
96+
cmdline = 'python -msphinx -M {} {} {}'.format(builder, DOCS_SRCDIR, DOCS_BUILDDIR)
97+
context.run(cmdline)
98+
namespace.add_task(docs)
99+
100+
@invoke.task
101+
def docs_clean(context):
102+
"Remove rendered documentation"
103+
#pylint: disable=unused-argument
104+
rmrf(DOCS_BUILDDIR)
105+
namespace_clean.add_task(docs_clean, name='docs')
106+
107+
@invoke.task
108+
def livehtml(context):
109+
"Launch webserver on http://localhost:8000 with rendered documentation"
110+
builder = 'html'
111+
outputdir = os.path.join(DOCS_BUILDDIR, builder)
112+
cmdline = 'sphinx-autobuild -b {} {} {}'.format(builder, DOCS_SRCDIR, outputdir)
113+
context.run(cmdline, pty=True)
114+
namespace.add_task(livehtml)
115+
116+
117+
#####
118+
#
119+
# build and distribute
120+
#
121+
#####
122+
BUILDDIR = 'build'
123+
DISTDIR = 'dist'
124+
125+
@invoke.task
126+
def build_clean(context):
127+
"Remove the build directory"
128+
#pylint: disable=unused-argument
129+
rmrf(BUILDDIR)
130+
namespace_clean.add_task(build_clean, 'build')
131+
132+
@invoke.task
133+
def dist_clean(context):
134+
"Remove the dist directory"
135+
#pylint: disable=unused-argument
136+
rmrf(DISTDIR)
137+
namespace_clean.add_task(dist_clean, 'dist')
138+
139+
@invoke.task
140+
def eggs_clean(context):
141+
"Remove egg directories"
142+
#pylint: disable=unused-argument
143+
dirs = set()
144+
dirs.add('.eggs')
145+
for name in os.listdir(os.curdir):
146+
if name.endswith('.egg-info'):
147+
dirs.add(name)
148+
if name.endswith('.egg'):
149+
dirs.add(name)
150+
rmrf(dirs)
151+
namespace_clean.add_task(eggs_clean, 'eggs')
152+
153+
@invoke.task
154+
def pycache_clean(context):
155+
"Remove __pycache__ directories"
156+
#pylint: disable=unused-argument
157+
dirs = set()
158+
for root, dirnames, _ in os.walk(os.curdir):
159+
if '__pycache__' in dirnames:
160+
dirs.add(os.path.join(root, '__pycache__'))
161+
print("Removing __pycache__ directories")
162+
rmrf(dirs, verbose=False)
163+
namespace_clean.add_task(pycache_clean, 'pycache')
164+
165+
#
166+
# make a dummy clean task which runs all the tasks in the clean namespace
167+
clean_tasks = list(namespace_clean.tasks.values())
168+
@invoke.task(pre=list(namespace_clean.tasks.values()), default=True)
169+
def clean_all(context):
170+
"Run all clean tasks"
171+
#pylint: disable=unused-argument
172+
pass
173+
namespace_clean.add_task(clean_all, 'all')
174+
175+
@invoke.task(pre=[clean_all])
176+
def sdist(context):
177+
"Create a source distribution"
178+
context.run('python setup.py sdist')
179+
namespace.add_task(sdist)
180+
181+
@invoke.task(pre=[clean_all])
182+
def wheel(context):
183+
"Build a wheel distribution"
184+
context.run('python setup.py bdist_wheel')
185+
namespace.add_task(wheel)
186+
187+
@invoke.task(pre=[sdist, wheel])
188+
def pypi(context):
189+
"Build and upload a distribution to pypi"
190+
context.run('twine upload dist/*')
191+
namespace.add_task(pypi)
192+
193+
@invoke.task(pre=[sdist, wheel])
194+
def pypi_test(context):
195+
"Build and upload a distribution to https://test.pypi.org"
196+
context.run('twine upload --repository-url https://test.pypi.org/legacy/ dist/*')
197+
namespace.add_task(pypi_test)
198+

0 commit comments

Comments
 (0)