Coverage for tests/test_styles.py: 100%
65 statements
« prev ^ index » next coverage.py v7.17.0, created at 2026-10-31 22:06 +0000
« prev ^ index » next coverage.py v7.17.0, created at 2026-10-31 22:06 +0000
1"""Tests for styles and exporters."""
3from __future__ import annotations
5import dataclasses
6import pathlib
8import pytest
10import coursebook
11from coursebook import outline
14@pytest.mark.parametrize(('name', 'expected'), [
15 ('law review', coursebook.LawReview),
16 ('Law_Review', coursebook.LawReview),
17 ('book', coursebook.Book),
18 ('Coursebook', coursebook.Coursebook),
19 ('textbook', coursebook.Coursebook)])
20def test_get_style(name: str, expected: type[coursebook.Style]) -> None:
21 """Tests choosing styles by name and alias."""
22 assert type(coursebook.get_style(name)) is expected
25def test_unknown_style() -> None:
26 """Tests that an unknown style lists the known styles."""
27 with pytest.raises(ValueError, match = 'law_review'):
28 coursebook.get_style('memo')
29 with pytest.raises(ValueError, match = 'unknown style'):
30 coursebook.get_style('style')
33def test_style_overrides() -> None:
34 """Tests that overrides replace defaults and `None` is ignored."""
35 style = coursebook.get_style(
36 'law review', number_headings = False, table_of_contents = None)
37 assert style.number_headings is False
38 assert style.table_of_contents is False
41def test_format_heading() -> None:
42 """Tests headings with and without labels."""
43 entry = outline.OutlineEntry(label = 'IV', title = 'Conclusion')
44 assert coursebook.LawReview().format_heading(entry) == 'IV. Conclusion'
45 assert coursebook.Book().format_heading(entry) == 'Conclusion'
46 preface = outline.OutlineEntry(label = '', title = 'Preface')
47 assert coursebook.LawReview().format_heading(preface) == 'Preface'
50def test_custom_style_is_registered() -> None:
51 """Tests that a subclass of `Style` can be chosen by name."""
53 @dataclasses.dataclass
54 class SeminarPaper(coursebook.Coursebook):
55 number_headings: bool = True
57 style = coursebook.get_style('Seminar Paper')
58 assert isinstance(style, SeminarPaper)
59 assert style.sections == ('text', 'slides', 'notes')
62@pytest.mark.parametrize(('name', 'expected'), [
63 ('word', coursebook.WordExporter),
64 ('DOCX', coursebook.WordExporter),
65 ('PowerPoint', coursebook.PowerPointExporter),
66 ('pdf', coursebook.PdfExporter),
67 ('HTML', coursebook.HtmlExporter),
68 ('word_exporter', coursebook.WordExporter)])
69def test_get_exporter(name: str, expected: type[coursebook.Exporter]) -> None:
70 """Tests choosing exporters by name and alias."""
71 assert type(coursebook.get_exporter(name)) is expected
74def test_unknown_exporter() -> None:
75 """Tests that an unknown format lists the known formats."""
76 with pytest.raises(ValueError, match = 'powerpoint'):
77 coursebook.get_exporter('epub')
80def test_exporter_arguments(tmp_path: pathlib.Path) -> None:
81 """Tests the pandoc arguments for each exporter."""
82 options = coursebook.ExportOptions(
83 template = tmp_path / 'reference.docx',
84 resource_paths = [tmp_path],
85 bibliography = [tmp_path / 'refs.bib'],
86 csl = tmp_path / 'style.csl',
87 table_of_contents = True)
88 word = coursebook.WordExporter().get_arguments(options)
89 assert f'--reference-doc={tmp_path / "reference.docx"}' in word
90 assert '--citeproc' in word
91 assert f'--csl={tmp_path / "style.csl"}' in word
92 assert '--toc' in word
93 slides = coursebook.PowerPointExporter().get_arguments(options)
94 assert '--slide-level=2' in slides
95 assert '--toc' not in slides
98def test_formatting_metadata() -> None:
99 """Tests the template variables for PDF and HTML files."""
100 options = coursebook.ExportOptions(
101 metadata = {'title': 'T'},
102 formatting = coursebook.LawReview().formatting)
103 pdf = coursebook.PdfExporter().get_metadata(options)
104 assert pdf['mainfont'] == 'Times New Roman'
105 assert pdf['fontsize'] == '12pt'
106 assert pdf['margin'] == {'x': '1.0in', 'y': '1.0in'}
107 assert pdf['page-numbering'] == '1'
108 assert '#show heading.where(level: 1): upper' in pdf['header-includes']
109 assert pdf['header-includes'].endswith('```\n')
110 html = coursebook.HtmlExporter().get_metadata(options)
111 assert html['mainfont'] == 'Times New Roman, serif'
112 assert 'text-transform: uppercase' in html['header-includes']
113 plain = coursebook.HtmlExporter().get_metadata(
114 coursebook.ExportOptions(metadata = {'title': 'T'}))
115 assert plain == {'title': 'T'}
118def test_exporter_sections() -> None:
119 """Tests which sections each exporter can export."""
120 assert coursebook.PowerPointExporter.sections == ('slides',)
121 for exporter in (
122 coursebook.WordExporter, coursebook.PdfExporter,
123 coursebook.HtmlExporter):
124 assert exporter.sections == ('text', 'notes')