Commit 7a50beab authored by Matthieu Boileau's avatar Matthieu Boileau
Browse files

Handle wrong notebook format

parent babaf690
...@@ -7,6 +7,7 @@ from pprint import pformat ...@@ -7,6 +7,7 @@ from pprint import pformat
import jinja2 import jinja2
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
import frontmatter import frontmatter
import sys
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
logging.basicConfig(level=logging.INFO) logging.basicConfig(level=logging.INFO)
...@@ -62,14 +63,18 @@ class HomePage(Page): ...@@ -62,14 +63,18 @@ class HomePage(Page):
chapter_no = int(re.match(r'(\d+)\-', path.stem).group(1)) chapter_no = int(re.match(r'(\d+)\-', path.stem).group(1))
nb = nbformat.read(str(path), as_version=4) nb = nbformat.read(str(path), as_version=4)
assert nb.cells[0].cell_type == 'markdown', nb.cells[0].cell_type if nb.cells[0].cell_type != 'markdown':
log.error(f"The first cell of the notebook {path} should be Markdown type " +
f"({nb.cells[0].cell_type} instead).")
sys.exit()
lines = nb.cells[0].source.splitlines() lines = nb.cells[0].source.splitlines()
if lines[0].startswith('# '): if lines[0].startswith('# '):
header = lines[0][2:] header = lines[0][2:]
elif len(lines) > 1 and lines[1].startswith('==='): elif len(lines) > 1 and lines[1].startswith('==='):
header = lines[0] header = lines[0]
else: else:
assert False, "No heading found in {}".format(path) log.error(f"No heading found in {path}")
sys.exit()
assert path.suffix == '.ipynb', path assert path.suffix == '.ipynb', path
......
...@@ -17,22 +17,28 @@ def test_get_help_epilog(): ...@@ -17,22 +17,28 @@ def test_get_help_epilog():
get_help_epilog() get_help_epilog()
@pytest.fixture def _create_project(tmpdir, sample=Path('sample')):
def create_project(tmpdir):
"""Create a sample nbcourse project""" """Create a sample nbcourse project"""
p = tmpdir.mkdir("test_project") p = tmpdir.mkdir("test_project")
os.chdir(p) os.chdir(p)
initialize() initialize()
# Create a link to sample notebooks # Create a link to sample notebooks
nb = Path('sample') nb = Path(sample)
nb.symlink_to(TESTS_PATH / 'sample', target_is_directory=True) nb.symlink_to(TESTS_PATH / sample, target_is_directory=True)
# Create a link to sample yaml file # Create a link to sample yaml file
yaml_file = Path('nbcourse.yml') yaml_file = Path('nbcourse.yml')
yaml_file.unlink() yaml_file.unlink()
yaml_file.symlink_to(TESTS_PATH / 'sample' / 'nbcourse.yml') yaml_file.symlink_to(TESTS_PATH / sample / 'nbcourse.yml')
@pytest.fixture
def create_project(tmpdir):
_create_project(tmpdir)
@pytest.fixture
def create_wrong_project(tmpdir):
_create_project(tmpdir, sample=Path('wrong_sample'))
def test_minimal_nbcourse(create_project): def test_minimal_nbcourse(create_project):
"""Only test nbcourse object instantiation""" """Only test nbcourse object instantiation"""
...@@ -64,3 +70,11 @@ def test_nbcourse_clean(create_project): ...@@ -64,3 +70,11 @@ def test_nbcourse_clean(create_project):
course.conf['book'] course.conf['book']
course.build(["-n 4"]) course.build(["-n 4"])
course.build(["clean"]) course.build(["clean"])
def test_nbcourse_wrong_build(create_wrong_project):
"""Test sample build with nbcourse.yml sample file"""
course = NbCourse(Path('nbcourse.yml'))
course.conf['book']
with pytest.raises(SystemExit):
assert course.build(["-n 4"]) == 2
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The Zen of Python, by Tim Peters\n",
"\n",
"Beautiful is better than ugly.\n",
"Explicit is better than implicit.\n",
"Simple is better than complex.\n",
"Complex is better than complicated.\n",
"Flat is better than nested.\n",
"Sparse is better than dense.\n",
"Readability counts.\n",
"Special cases aren't special enough to break the rules.\n",
"Although practicality beats purity.\n",
"Errors should never pass silently.\n",
"Unless explicitly silenced.\n",
"In the face of ambiguity, refuse the temptation to guess.\n",
"There should be one-- and preferably only one --obvious way to do it.\n",
"Although that way may not be obvious at first unless you're Dutch.\n",
"Now is better than never.\n",
"Although never is often better than *right* now.\n",
"If the implementation is hard to explain, it's a bad idea.\n",
"If the implementation is easy to explain, it may be a good idea.\n",
"Namespaces are one honking great idea -- let's do more of those!\n"
]
}
],
"source": [
"import this"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Introduction\n",
"\n",
"![Python logo](fig/python-logo_full.png)\n",
"\n",
"Link to [another part of this notebook](#Just-a-subheading), and to [chapter 2](02-in-which-we.ipynb)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"for a in range(1, 6):\n",
" print(a, 'squared is', a**2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Just a subheading\n",
"\n",
"Here's some content."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"*These sample notebooks are from [bookbook project](https://github.com/takluyver/bookbook).*"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.6"
},
"toc": {
"base_numbering": 1,
"nav_menu": {},
"number_sections": true,
"sideBar": true,
"skip_h1_title": false,
"title_cell": "Table of Contents",
"title_sidebar": "Contents",
"toc_cell": false,
"toc_position": {},
"toc_section_display": true,
"toc_window_display": false
}
},
"nbformat": 4,
"nbformat_minor": 1
}
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Part the Second\n",
"\n",
"Cross reference to [subheading in chapter 1](01-introduction.ipynb#Just-a-subheading).\n",
"\n",
"We would like to reference the external python file [helloworld.py](exos/helloworld.py)."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.4"
},
"toc": {
"base_numbering": 1,
"nav_menu": {},
"number_sections": true,
"sideBar": true,
"skip_h1_title": false,
"title_cell": "Table of Contents",
"title_sidebar": "Contents",
"toc_cell": false,
"toc_position": {},
"toc_section_display": true,
"toc_window_display": false
}
},
"nbformat": 4,
"nbformat_minor": 1
}
\ No newline at end of file
../sample/a_dir
\ No newline at end of file
../sample/exos/
\ No newline at end of file
../sample/fig/
\ No newline at end of file
title: A sample course
slug_title: sample-course
subtitle: Not very useful
favicon: fig/favicon.ico
book:
file: sample-course.pdf
picture:
path: fig/python-logo_full.png
width: 300px
alt: Logo Python
authors:
- name: Nobody
email: nobody@nowhere.com
- Somebody
chapter_preview_only:
- 2
links:
manual:
title: Manual
target: manual.html
binder:
title: Run
target: https://mybinder.org
book:
title: PDF version
gitlab:
title: Sources
target: https://gitlab.com
archive:
title: Complete archive
license:
text: Content available under license
target: https://creativecommons.org/licenses/by-sa/4.0/
icon:
path: img/by-sa.svg
width: 70px
local_reveal: True
nb:
dir: 'wrong_sample'
material:
- fig
- exos
- a_dir/a_file.txt
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment