Skip to content

Commit 77fd8bc

Browse files
authored
Convert the unittest to the pytest conventions (ipython#27)
* Pin wheel, twine, and setuptools versions to allow a markdown description on the warehouse * Rewrite the unittests as pytests and add a watcher for improved development in lab. * yaml/pyyaml#126 install yaml from github to pass 3.7dev
1 parent ecaa5f3 commit 77fd8bc

File tree

5 files changed

+262
-4
lines changed

5 files changed

+262
-4
lines changed

requirements.txt

+3-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,6 @@ black
33
pytest
44
pytest-cov
55
tox
6-
importnb
6+
importnb
7+
git+https://github.com/yaml/pyyaml.git
8+
watchdog

setup.py

+11-2
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,24 @@
1515
author="deathbeds",
1616
author_email="[email protected]",
1717
description="Import .ipynb files as modules in the system path.",
18+
1819
long_description=(
1920
(here / "readme.md").read_text() + "\n\n" +
2021
(here / "changelog.md").read_text()
2122
),
22-
# long_description_content_type='text/markdown',
23+
24+
long_description_content_type='text/markdown',
25+
setup_requires=[
26+
'pytest-runner',
27+
'setuptools>=38.6.0',
28+
'twine>=1.11.0',
29+
'wheel>=0.31.0'
30+
],
31+
2332
url="https://github.com/deathbeds/importnb",
2433
python_requires=">=3.6",
2534
license="BSD-3-Clause",
26-
setup_requires=['pytest-runner'],
35+
2736
tests_require=['pytest'],
2837
install_requires=[
2938
"dataclasses",

src/importnb/_version.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.2.4"
1+
__version__ = "0.2.5"

tests/test_importnb.ipynb

+241
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": 70,
6+
"metadata": {},
7+
"outputs": [],
8+
"source": [
9+
"from importnb import Notebook, Partial, reload, load_ipython_extension, unload_ipython_extension\n",
10+
"from nbformat import v4\n",
11+
"from pathlib import Path\n",
12+
"import shutil, os, functools\n",
13+
"from pytest import fixture, mark\n"
14+
]
15+
},
16+
{
17+
"cell_type": "code",
18+
"execution_count": 65,
19+
"metadata": {},
20+
"outputs": [],
21+
"source": [
22+
"source =\"\"\"\n",
23+
"foo = 42\n",
24+
"assert {}\n",
25+
"bar= 100\n",
26+
"\"\"\""
27+
]
28+
},
29+
{
30+
"cell_type": "code",
31+
"execution_count": 66,
32+
"metadata": {},
33+
"outputs": [],
34+
"source": [
35+
"def new_notebook(str='foo'):\n",
36+
" return v4.writes(v4.new_notebook(cells=[\n",
37+
" v4.new_code_cell(source.format(str))\n",
38+
" ]))"
39+
]
40+
},
41+
{
42+
"cell_type": "code",
43+
"execution_count": 67,
44+
"metadata": {},
45+
"outputs": [],
46+
"source": [
47+
"@fixture(scope='function')\n",
48+
"def single_file(request):\n",
49+
" file = Path('foobar.ipynb')\n",
50+
" file.write_text(new_notebook())\n",
51+
" request.addfinalizer(functools.partial(os.remove, file))\n",
52+
" return file"
53+
]
54+
},
55+
{
56+
"cell_type": "code",
57+
"execution_count": 71,
58+
"metadata": {},
59+
"outputs": [],
60+
"source": [
61+
"@fixture\n",
62+
"def clean_up_file(single_file, request):\n",
63+
" def clean_sys():\n",
64+
" import sys\n",
65+
" del sys.modules['foobar']\n",
66+
" sys.path_importer_cache.clear()\n",
67+
" request.addfinalizer(clean_sys)"
68+
]
69+
},
70+
{
71+
"cell_type": "code",
72+
"execution_count": 72,
73+
"metadata": {},
74+
"outputs": [],
75+
"source": [
76+
"def validate_reload(module):\n",
77+
" try:\n",
78+
" reload(module)\n",
79+
" assert False, \"\"\"The reload should fail.\"\"\"\n",
80+
" except:\n",
81+
" assert True, \"\"\"Cannot reload a file outside of a context manager\"\"\"\n",
82+
"\n",
83+
" with Notebook():\n",
84+
" assert reload(module)"
85+
]
86+
},
87+
{
88+
"cell_type": "code",
89+
"execution_count": 57,
90+
"metadata": {},
91+
"outputs": [],
92+
"source": [
93+
"def test_single_file_with_context(clean_up_file):\n",
94+
" with Notebook():\n",
95+
" import foobar\n",
96+
" assert foobar.foo == 42 and foobar.bar == 100\n",
97+
" \n",
98+
" validate_reload(foobar)"
99+
]
100+
},
101+
{
102+
"cell_type": "code",
103+
"execution_count": null,
104+
"metadata": {},
105+
"outputs": [],
106+
"source": [
107+
"@fixture\n",
108+
"def extension(clean_up_file, request):\n",
109+
" load_ipython_extension()\n",
110+
" request.addfinalizer(unload_ipython_extension)"
111+
]
112+
},
113+
{
114+
"cell_type": "code",
115+
"execution_count": null,
116+
"metadata": {},
117+
"outputs": [],
118+
"source": [
119+
"def test_single_with_extension(extension):\n",
120+
" import foobar\n",
121+
" assert foobar.foo == 42 and foobar.bar == 100"
122+
]
123+
},
124+
{
125+
"cell_type": "code",
126+
"execution_count": 49,
127+
"metadata": {},
128+
"outputs": [],
129+
"source": [
130+
"@mark.xfail\n",
131+
"def test_single_file_relative(single_file):\n",
132+
" with Notebook():\n",
133+
" from . import foobar"
134+
]
135+
},
136+
{
137+
"cell_type": "code",
138+
"execution_count": 46,
139+
"metadata": {},
140+
"outputs": [],
141+
"source": [
142+
"@fixture\n",
143+
"def single_directory(request):\n",
144+
" root = Path('a_test_package')\n",
145+
" root.mkdir(exist_ok=True)\n",
146+
" (root / 'foobar.ipynb').write_text(new_notebook())\n",
147+
" (root / 'failure.ipynb').write_text(new_notebook('False'))\n",
148+
" (root / 'py.py').write_text(\"\"\"from . import foobar\\nbaz = 'foobar'\"\"\")\n",
149+
" request.addfinalizer(functools.partial(shutil.rmtree, root))\n",
150+
" return root"
151+
]
152+
},
153+
{
154+
"cell_type": "code",
155+
"execution_count": null,
156+
"metadata": {},
157+
"outputs": [],
158+
"source": [
159+
"@mark.xfail\n",
160+
"def test_single_file_without_context():\n",
161+
" import foobar"
162+
]
163+
},
164+
{
165+
"cell_type": "code",
166+
"execution_count": 53,
167+
"metadata": {},
168+
"outputs": [],
169+
"source": [
170+
"def test_package(single_directory):\n",
171+
" with Notebook():\n",
172+
" from a_test_package import foobar, py\n",
173+
" \n",
174+
" assert foobar.foo == 42 and foobar.bar == 100\n",
175+
" assert py.baz == 'foobar'\n",
176+
" assert py.foobar is foobar\n",
177+
" validate_reload(foobar)"
178+
]
179+
},
180+
{
181+
"cell_type": "code",
182+
"execution_count": 53,
183+
"metadata": {},
184+
"outputs": [],
185+
"source": [
186+
"@mark.xfail\n",
187+
"def test_package_failure(single_directory):\n",
188+
" with Notebook():\n",
189+
" from a_test_package import failure"
190+
]
191+
},
192+
{
193+
"cell_type": "code",
194+
"execution_count": 53,
195+
"metadata": {},
196+
"outputs": [],
197+
"source": [
198+
"def test_package_failure_partial(single_directory):\n",
199+
" with Partial():\n",
200+
" from a_test_package import failure\n",
201+
" \n",
202+
" assert isinstance(failure.__exception__, AssertionError), \"\"\"\n",
203+
" The wrong error was returned likely because of importnb.\"\"\"\n",
204+
"\n",
205+
" from traceback import print_tb\n",
206+
" from io import StringIO\n",
207+
" s = StringIO()\n",
208+
" print_tb(failure.__exception__.__traceback__, file=s)\n",
209+
" assert \"\"\"a_test_package/failure.ipynb\", line 11, in <module>\\n\"\"\" in s.getvalue(), \"\"\"Traceback is not satisfied\"\"\""
210+
]
211+
},
212+
{
213+
"cell_type": "code",
214+
"execution_count": null,
215+
"metadata": {},
216+
"outputs": [],
217+
"source": []
218+
}
219+
],
220+
"metadata": {
221+
"kernelspec": {
222+
"display_name": "p6",
223+
"language": "python",
224+
"name": "other-env"
225+
},
226+
"language_info": {
227+
"codemirror_mode": {
228+
"name": "ipython",
229+
"version": 3
230+
},
231+
"file_extension": ".py",
232+
"mimetype": "text/x-python",
233+
"name": "python",
234+
"nbconvert_exporter": "python",
235+
"pygments_lexer": "ipython3",
236+
"version": "3.6.3"
237+
}
238+
},
239+
"nbformat": 4,
240+
"nbformat_minor": 2
241+
}

tricks.yaml

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
tricks:
2+
- watchdog.tricks.ShellCommandTrick:
3+
patterns:
4+
- ./tests/test_*.ipynb
5+
shell_command: |
6+
pytest tests/test_importnb.ipynb --verbose --capture=no

0 commit comments

Comments
 (0)