updated with functional changes, testing
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
from epubmaker.models import Name, Series, Image, Section, Book, BuildContext
|
||||
|
||||
|
||||
def test_name_defaults():
|
||||
n = Name()
|
||||
assert n.first == ""
|
||||
assert n.last == ""
|
||||
|
||||
|
||||
def test_series_defaults():
|
||||
s = Series()
|
||||
assert s.number == ""
|
||||
assert s.name == ""
|
||||
|
||||
|
||||
def test_image_defaults():
|
||||
img = Image()
|
||||
assert img.name == ""
|
||||
assert img.type == ""
|
||||
assert img.alt == ""
|
||||
assert img.caption == ""
|
||||
|
||||
|
||||
def test_section_defaults():
|
||||
s = Section()
|
||||
assert s.type == ""
|
||||
assert s.name == ""
|
||||
assert s.title == ""
|
||||
assert s.body == ""
|
||||
|
||||
|
||||
def test_book_defaults():
|
||||
b = Book()
|
||||
assert b.filename == ""
|
||||
assert b.title == ""
|
||||
assert b.titlesort == ""
|
||||
assert b.publisher == ""
|
||||
assert b.isbn == ""
|
||||
assert b.uuid == ""
|
||||
assert b.author == []
|
||||
assert b.images == []
|
||||
assert b.sections == []
|
||||
|
||||
|
||||
def test_book_nested_objects():
|
||||
b = Book()
|
||||
assert isinstance(b.series, Series)
|
||||
assert isinstance(b.artist, Name)
|
||||
assert isinstance(b.editor, Name)
|
||||
assert isinstance(b.cover, Image)
|
||||
|
||||
|
||||
def test_book_author_lists_are_independent():
|
||||
b1 = Book()
|
||||
b2 = Book()
|
||||
b1.author.append(Name(first="Jane", last="Doe"))
|
||||
assert len(b2.author) == 0
|
||||
|
||||
|
||||
def test_build_context_defaults():
|
||||
ctx = BuildContext()
|
||||
assert isinstance(ctx.book, Book)
|
||||
assert ctx.verbose is False
|
||||
assert ctx.in_section is False
|
||||
|
||||
|
||||
def test_build_context_books_are_independent():
|
||||
ctx1 = BuildContext()
|
||||
ctx2 = BuildContext()
|
||||
ctx1.book.title = "Book One"
|
||||
assert ctx2.book.title == ""
|
||||
@@ -0,0 +1,249 @@
|
||||
import pytest
|
||||
from epubmaker.models import BuildContext
|
||||
from epubmaker.parser import extract, identify, parse_book
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def ctx():
|
||||
return BuildContext()
|
||||
|
||||
|
||||
def test_extract_returns_inner_content():
|
||||
assert extract("<!-- Title: Foo Bar -->") == "Title: Foo Bar"
|
||||
|
||||
|
||||
def test_extract_with_newline():
|
||||
assert extract("<!-- Title: Foo Bar -->\n") == "Title: Foo Bar"
|
||||
|
||||
|
||||
def test_extract_returns_none_for_non_comment():
|
||||
assert extract("<p>Not a comment</p>") is None
|
||||
|
||||
|
||||
def test_identify_directory(ctx):
|
||||
identify("<!-- Directory: mybook -->", ctx)
|
||||
assert ctx.book.directory == "mybook"
|
||||
assert ctx.in_section is False
|
||||
|
||||
|
||||
def test_identify_title_plain(ctx):
|
||||
identify("<!-- Title: My Book -->", ctx)
|
||||
assert ctx.book.title == "My Book"
|
||||
assert ctx.book.titlesort == ""
|
||||
|
||||
|
||||
def test_identify_title_the(ctx):
|
||||
identify("<!-- Title: The Great Book -->", ctx)
|
||||
assert ctx.book.title == "The Great Book"
|
||||
assert ctx.book.titlesort == "Great Book, The"
|
||||
|
||||
|
||||
def test_identify_title_a(ctx):
|
||||
identify("<!-- Title: A Good Story -->", ctx)
|
||||
assert ctx.book.title == "A Good Story"
|
||||
assert ctx.book.titlesort == "Good Story, A"
|
||||
|
||||
|
||||
def test_identify_title_an(ctx):
|
||||
identify("<!-- Title: An Old Tale -->", ctx)
|
||||
assert ctx.book.title == "An Old Tale"
|
||||
assert ctx.book.titlesort == "Old Tale, An"
|
||||
|
||||
|
||||
def test_identify_author(ctx):
|
||||
identify("<!-- Author: Smith, John -->", ctx)
|
||||
assert len(ctx.book.author) == 1
|
||||
assert ctx.book.author[0].last == "Smith"
|
||||
assert ctx.book.author[0].first == "John"
|
||||
|
||||
|
||||
def test_identify_multiple_authors(ctx):
|
||||
identify("<!-- Author: Smith, John -->", ctx)
|
||||
identify("<!-- Author: Jones, Jane -->", ctx)
|
||||
assert len(ctx.book.author) == 2
|
||||
assert ctx.book.author[1].last == "Jones"
|
||||
|
||||
|
||||
def test_identify_editor(ctx):
|
||||
identify("<!-- Editor: Brown, Alice -->", ctx)
|
||||
assert ctx.book.editor.last == "Brown"
|
||||
assert ctx.book.editor.first == "Alice"
|
||||
|
||||
|
||||
def test_identify_publisher(ctx):
|
||||
identify("<!-- Publisher: Acme Press -->", ctx)
|
||||
assert ctx.book.publisher == "Acme Press"
|
||||
|
||||
|
||||
def test_identify_copyright(ctx):
|
||||
identify("<!-- Copyright: 2024 Author -->", ctx)
|
||||
assert ctx.book.copyright == "2024 Author"
|
||||
|
||||
|
||||
def test_identify_isbn(ctx):
|
||||
identify("<!-- ISBN: 978-0-000-00000-0 -->", ctx)
|
||||
assert ctx.book.isbn == "978-0-000-00000-0"
|
||||
|
||||
|
||||
def test_identify_uuid_explicit(ctx):
|
||||
identify("<!-- UUID: abc-123 -->", ctx)
|
||||
assert ctx.book.uuid == "abc-123"
|
||||
|
||||
|
||||
def test_identify_uuid_empty_generates_uuid(ctx):
|
||||
identify("<!-- UUID: -->", ctx)
|
||||
assert ctx.book.uuid != ""
|
||||
assert ctx.book.uuid is not None
|
||||
|
||||
|
||||
def test_identify_source(ctx):
|
||||
identify("<!-- Source: Some Original Work -->", ctx)
|
||||
assert ctx.book.source == "Some Original Work"
|
||||
|
||||
|
||||
def test_identify_subjects(ctx):
|
||||
identify("<!-- Subjects: Fiction, Mystery -->", ctx)
|
||||
assert ctx.book.subjects == "Fiction, Mystery"
|
||||
|
||||
|
||||
def test_identify_series(ctx):
|
||||
identify("<!-- Series: 1 My Series Name -->", ctx)
|
||||
assert ctx.book.series.number == "1"
|
||||
assert ctx.book.series.name == "My Series Name"
|
||||
|
||||
|
||||
def test_identify_cover(ctx):
|
||||
identify("<!-- Cover: cover.jpeg -->", ctx)
|
||||
assert ctx.book.cover.name == "cover"
|
||||
assert ctx.book.cover.type == "jpeg"
|
||||
|
||||
|
||||
def test_identify_text_section(ctx):
|
||||
identify("<!-- Text: chapter1 Chapter One -->", ctx)
|
||||
assert ctx.in_section is True
|
||||
assert len(ctx.book.sections) == 1
|
||||
assert ctx.book.sections[0].type == "text"
|
||||
assert ctx.book.sections[0].name == "chapter1"
|
||||
assert ctx.book.sections[0].title == "Chapter One"
|
||||
|
||||
|
||||
def test_identify_toc_section(ctx):
|
||||
identify("<!-- TOC: toc Table of Contents -->", ctx)
|
||||
assert ctx.in_section is True
|
||||
assert ctx.book.sections[0].type == "toc"
|
||||
|
||||
|
||||
def test_identify_title_page(ctx):
|
||||
identify("<!-- TitlePage: tp Title Page -->", ctx)
|
||||
assert ctx.book.sections[0].type == "title"
|
||||
|
||||
|
||||
def test_identify_copyright_page(ctx):
|
||||
identify("<!-- CopyrightPage: cp Copyright -->", ctx)
|
||||
assert ctx.book.sections[0].type == "copyright-page"
|
||||
|
||||
|
||||
def test_identify_dedication(ctx):
|
||||
identify("<!-- Dedication: ded For someone -->", ctx)
|
||||
assert ctx.book.sections[0].type == "dedication"
|
||||
|
||||
|
||||
def test_identify_foreward(ctx):
|
||||
identify("<!-- Foreward: fw Foreword -->", ctx)
|
||||
assert ctx.book.sections[0].type == "forward"
|
||||
|
||||
|
||||
def test_identify_notes(ctx):
|
||||
identify("<!-- Notes: notes Notes -->", ctx)
|
||||
assert ctx.book.sections[0].type == "notes"
|
||||
|
||||
|
||||
def test_identify_acknowledgement(ctx):
|
||||
identify("<!-- Acknowledgement: ack Acknowledgements -->", ctx)
|
||||
assert ctx.book.sections[0].type == "acknowledgement"
|
||||
|
||||
|
||||
def test_identify_metadata_clears_in_section(ctx):
|
||||
identify("<!-- Text: ch1 Chapter One -->", ctx)
|
||||
assert ctx.in_section is True
|
||||
identify("<!-- Title: My Book -->", ctx)
|
||||
assert ctx.in_section is False
|
||||
|
||||
|
||||
def test_identify_image_jpeg(ctx):
|
||||
identify("<!-- Text: ch1 Chapter One -->", ctx)
|
||||
identify("<!-- Image: photo.jpg Alt text::Caption text -->", ctx)
|
||||
assert len(ctx.book.images) == 1
|
||||
assert ctx.book.images[0].name == "photo.jpg"
|
||||
assert ctx.book.images[0].type == "jpeg"
|
||||
assert ctx.book.images[0].alt == "Alt text"
|
||||
assert ctx.book.images[0].caption == "Caption text"
|
||||
|
||||
|
||||
def test_identify_image_png(ctx):
|
||||
identify("<!-- Text: ch1 Chapter One -->", ctx)
|
||||
identify("<!-- Image: photo.png Alt text::Caption -->", ctx)
|
||||
assert ctx.book.images[0].type == "png"
|
||||
|
||||
|
||||
def test_identify_image_appends_to_section_body(ctx):
|
||||
identify("<!-- Text: ch1 Chapter One -->", ctx)
|
||||
identify("<!-- Image: photo.jpg Alt::Caption -->", ctx)
|
||||
assert "photo.jpg" in ctx.book.sections[-1].body
|
||||
|
||||
|
||||
def test_identify_image_with_caption_uses_div(ctx):
|
||||
identify("<!-- Text: ch1 Chapter One -->", ctx)
|
||||
identify("<!-- Image: photo.jpg Alt::My Caption -->", ctx)
|
||||
assert '<div class="center group">' in ctx.book.sections[-1].body
|
||||
assert "My Caption" in ctx.book.sections[-1].body
|
||||
|
||||
|
||||
def test_identify_image_without_caption_uses_img(ctx):
|
||||
identify("<!-- Text: ch1 Chapter One -->", ctx)
|
||||
identify("<!-- Image: photo.jpg Alt:: -->", ctx)
|
||||
body = ctx.book.sections[-1].body
|
||||
assert "<img" in body
|
||||
assert '<div class="center group">' not in body
|
||||
|
||||
|
||||
def test_identify_unknown_key_ignored(ctx):
|
||||
identify("<!-- UnknownKey: some value -->", ctx)
|
||||
assert ctx.book.title == ""
|
||||
assert ctx.book.directory == ""
|
||||
|
||||
|
||||
def test_parse_book_populates_book(tmp_path):
|
||||
source = tmp_path / "book.html"
|
||||
source.write_text(
|
||||
"<!-- Directory: mybook -->\n"
|
||||
"<!-- Title: Test Book -->\n"
|
||||
"<!-- Author: Doe, Jane -->\n"
|
||||
"<!-- Text: ch1 Chapter One -->\n"
|
||||
"<p>Body content</p>\n"
|
||||
)
|
||||
ctx = BuildContext()
|
||||
ctx.book.filename = str(source)
|
||||
parse_book(ctx)
|
||||
assert ctx.book.title == "Test Book"
|
||||
assert ctx.book.directory == "mybook"
|
||||
assert len(ctx.book.author) == 1
|
||||
assert ctx.book.author[0].last == "Doe"
|
||||
assert len(ctx.book.sections) == 1
|
||||
assert "<p>Body content</p>\n" in ctx.book.sections[0].body
|
||||
|
||||
|
||||
def test_parse_book_body_not_captured_outside_section(tmp_path):
|
||||
source = tmp_path / "book.html"
|
||||
source.write_text(
|
||||
"<!-- Title: Test Book -->\n"
|
||||
"<p>This is outside any section</p>\n"
|
||||
"<!-- Text: ch1 Chapter One -->\n"
|
||||
"<p>Inside section</p>\n"
|
||||
)
|
||||
ctx = BuildContext()
|
||||
ctx.book.filename = str(source)
|
||||
parse_book(ctx)
|
||||
assert len(ctx.book.sections) == 1
|
||||
assert "outside any section" not in ctx.book.sections[0].body
|
||||
assert "Inside section" in ctx.book.sections[0].body
|
||||
@@ -0,0 +1,243 @@
|
||||
import os
|
||||
import pytest
|
||||
from unittest.mock import patch
|
||||
from epubmaker.models import BuildContext, Book, Section, Image, Name
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def ctx(tmp_path):
|
||||
context = BuildContext()
|
||||
context.book.title = "Test Book"
|
||||
context.book.uuid = "test-uuid-1234"
|
||||
context.book.isbn = "978-0-000-00000-0"
|
||||
context.book.publisher = "Test Publisher"
|
||||
context.book.copyright = "2024 Test"
|
||||
context.book.subjects = "Fiction"
|
||||
context.book.source = "Original Source"
|
||||
context.book.publish_date = "2024-1-1"
|
||||
context.book.directory = str(tmp_path / "testbook")
|
||||
context.book.filename = str(tmp_path / "source" / "book.html")
|
||||
context.book.author.append(Name(first="Jane", last="Doe"))
|
||||
return context
|
||||
|
||||
|
||||
from epubmaker.writer import (
|
||||
write_structure, write_misc, write_ncx, write_toc,
|
||||
write_cover, write_contents, write_sections, write_illustrations,
|
||||
)
|
||||
|
||||
|
||||
# --- write_structure ---
|
||||
|
||||
def test_write_structure_creates_epub_directories(ctx):
|
||||
write_structure(ctx, overwrite=False)
|
||||
for subdir in ["META-INF", "OEBPS", "OEBPS/Images", "OEBPS/Styles", "OEBPS/Text"]:
|
||||
assert os.path.isdir(os.path.join(ctx.book.directory, subdir))
|
||||
|
||||
|
||||
def test_write_structure_exits_if_exists(ctx):
|
||||
os.makedirs(ctx.book.directory)
|
||||
with pytest.raises(SystemExit):
|
||||
write_structure(ctx, overwrite=False)
|
||||
|
||||
|
||||
def test_write_structure_overwrite_replaces_existing(ctx):
|
||||
os.makedirs(ctx.book.directory)
|
||||
sentinel = os.path.join(ctx.book.directory, "old_file.txt")
|
||||
open(sentinel, "w").close()
|
||||
write_structure(ctx, overwrite=True)
|
||||
assert os.path.isdir(ctx.book.directory)
|
||||
assert not os.path.exists(sentinel)
|
||||
|
||||
|
||||
# --- write_misc ---
|
||||
|
||||
def test_write_misc_mimetype_content(ctx):
|
||||
write_structure(ctx, overwrite=False)
|
||||
write_misc(ctx)
|
||||
with open(os.path.join(ctx.book.directory, "mimetype")) as f:
|
||||
assert f.read() == "application/epub+zip"
|
||||
|
||||
|
||||
def test_write_misc_container_xml_references_opf(ctx):
|
||||
write_structure(ctx, overwrite=False)
|
||||
write_misc(ctx)
|
||||
with open(os.path.join(ctx.book.directory, "META-INF", "container.xml")) as f:
|
||||
assert 'full-path="OEBPS/content.opf"' in f.read()
|
||||
|
||||
|
||||
def test_write_misc_ibooks_display_options_created(ctx):
|
||||
write_structure(ctx, overwrite=False)
|
||||
write_misc(ctx)
|
||||
path = os.path.join(ctx.book.directory, "META-INF", "com.apple.ibooks.display-options.xml")
|
||||
assert os.path.isfile(path)
|
||||
|
||||
|
||||
# --- write_ncx ---
|
||||
|
||||
def test_write_ncx_contains_title_and_uuid(ctx):
|
||||
write_structure(ctx, overwrite=False)
|
||||
write_ncx(ctx)
|
||||
with open(os.path.join(ctx.book.directory, "OEBPS", "toc.ncx")) as f:
|
||||
content = f.read()
|
||||
assert ctx.book.title in content
|
||||
assert ctx.book.uuid in content
|
||||
|
||||
|
||||
def test_write_ncx_includes_non_toc_sections(ctx):
|
||||
ctx.book.sections.append(Section(type="text", name="chapter1", title="Chapter One"))
|
||||
write_structure(ctx, overwrite=False)
|
||||
write_ncx(ctx)
|
||||
with open(os.path.join(ctx.book.directory, "OEBPS", "toc.ncx")) as f:
|
||||
content = f.read()
|
||||
assert "chapter1" in content
|
||||
assert "Chapter One" in content
|
||||
|
||||
|
||||
def test_write_ncx_excludes_toc_type_sections(ctx):
|
||||
ctx.book.sections.append(Section(type="toc", name="toc", title="Table of Contents"))
|
||||
write_structure(ctx, overwrite=False)
|
||||
write_ncx(ctx)
|
||||
with open(os.path.join(ctx.book.directory, "OEBPS", "toc.ncx")) as f:
|
||||
content = f.read()
|
||||
assert 'id ="toc"' not in content
|
||||
|
||||
|
||||
def test_write_ncx_play_order_increments(ctx):
|
||||
for i in range(3):
|
||||
ctx.book.sections.append(Section(type="text", name=f"ch{i}", title=f"Chapter {i}"))
|
||||
write_structure(ctx, overwrite=False)
|
||||
write_ncx(ctx)
|
||||
with open(os.path.join(ctx.book.directory, "OEBPS", "toc.ncx")) as f:
|
||||
content = f.read()
|
||||
assert 'playOrder="2"' in content
|
||||
assert 'playOrder="3"' in content
|
||||
assert 'playOrder="4"' in content
|
||||
|
||||
|
||||
# --- write_toc ---
|
||||
|
||||
def test_write_toc_writes_section_body(ctx):
|
||||
section = Section(body="<p>Contents here</p>\n")
|
||||
write_structure(ctx, overwrite=False)
|
||||
write_toc(ctx, section)
|
||||
with open(os.path.join(ctx.book.directory, "OEBPS", "toc.xhtml")) as f:
|
||||
content = f.read()
|
||||
assert "<p>Contents here</p>" in content
|
||||
assert "Table of Contents" in content
|
||||
|
||||
|
||||
# --- write_cover ---
|
||||
|
||||
def test_write_cover_creates_xhtml_with_title(ctx, tmp_path):
|
||||
source_images = tmp_path / "source" / "Images"
|
||||
source_images.mkdir(parents=True)
|
||||
(source_images / "cover.jpeg").write_bytes(b"fake")
|
||||
write_structure(ctx, overwrite=False)
|
||||
write_cover(ctx)
|
||||
with open(os.path.join(ctx.book.directory, "OEBPS", "Text", "cover.xhtml")) as f:
|
||||
content = f.read()
|
||||
assert ctx.book.title in content
|
||||
assert 'src="../Images/cover.jpeg"' in content
|
||||
|
||||
|
||||
def test_write_cover_copies_image_to_output(ctx, tmp_path):
|
||||
source_images = tmp_path / "source" / "Images"
|
||||
source_images.mkdir(parents=True)
|
||||
(source_images / "cover.jpeg").write_bytes(b"image-data")
|
||||
write_structure(ctx, overwrite=False)
|
||||
write_cover(ctx)
|
||||
assert os.path.isfile(os.path.join(ctx.book.directory, "OEBPS", "Images", "cover.jpeg"))
|
||||
|
||||
|
||||
# --- write_sections ---
|
||||
|
||||
def test_write_sections_creates_xhtml_per_section(ctx):
|
||||
ctx.book.sections.append(Section(type="text", name="chapter1", title="Chapter One", body="<p>Content</p>\n"))
|
||||
write_structure(ctx, overwrite=False)
|
||||
write_sections(ctx)
|
||||
path = os.path.join(ctx.book.directory, "OEBPS", "Text", "chapter1.xhtml")
|
||||
assert os.path.isfile(path)
|
||||
with open(path) as f:
|
||||
content = f.read()
|
||||
assert "Chapter One" in content
|
||||
assert "<p>Content</p>" in content
|
||||
|
||||
|
||||
def test_write_sections_routes_toc_to_toc_xhtml(ctx):
|
||||
ctx.book.sections.append(Section(type="toc", name="toc", title="Table of Contents", body="<p>toc</p>\n"))
|
||||
write_structure(ctx, overwrite=False)
|
||||
write_sections(ctx)
|
||||
assert os.path.isfile(os.path.join(ctx.book.directory, "OEBPS", "toc.xhtml"))
|
||||
assert not os.path.isfile(os.path.join(ctx.book.directory, "OEBPS", "Text", "toc.xhtml"))
|
||||
|
||||
|
||||
def test_write_sections_multiple_sections(ctx):
|
||||
for i in range(3):
|
||||
ctx.book.sections.append(Section(type="text", name=f"ch{i}", title=f"Chapter {i}", body=f"<p>ch{i}</p>\n"))
|
||||
write_structure(ctx, overwrite=False)
|
||||
write_sections(ctx)
|
||||
for i in range(3):
|
||||
assert os.path.isfile(os.path.join(ctx.book.directory, "OEBPS", "Text", f"ch{i}.xhtml"))
|
||||
|
||||
|
||||
# --- write_illustrations ---
|
||||
|
||||
def test_write_illustrations_skips_when_no_images(ctx):
|
||||
write_structure(ctx, overwrite=False)
|
||||
write_illustrations(ctx)
|
||||
assert not os.path.isfile(os.path.join(ctx.book.directory, "OEBPS", "Text", "illustrations.xhtml"))
|
||||
|
||||
|
||||
def test_write_illustrations_creates_file_with_image_links(ctx):
|
||||
ctx.book.images.append(Image(name="photo.jpg", caption="A scenic photo"))
|
||||
write_structure(ctx, overwrite=False)
|
||||
write_illustrations(ctx)
|
||||
path = os.path.join(ctx.book.directory, "OEBPS", "Text", "illustrations.xhtml")
|
||||
assert os.path.isfile(path)
|
||||
with open(path) as f:
|
||||
content = f.read()
|
||||
assert "photo.jpg" in content
|
||||
assert "A scenic photo" in content
|
||||
|
||||
|
||||
# --- write_contents ---
|
||||
|
||||
def test_write_contents_creates_opf_with_metadata(ctx):
|
||||
write_structure(ctx, overwrite=False)
|
||||
write_contents(ctx)
|
||||
with open(os.path.join(ctx.book.directory, "OEBPS", "content.opf")) as f:
|
||||
content = f.read()
|
||||
assert ctx.book.title in content
|
||||
assert ctx.book.publisher in content
|
||||
assert ctx.book.isbn in content
|
||||
|
||||
|
||||
def test_write_contents_includes_section_in_manifest(ctx):
|
||||
ctx.book.sections.append(Section(type="text", name="chapter1", title="Chapter One"))
|
||||
write_structure(ctx, overwrite=False)
|
||||
write_contents(ctx)
|
||||
with open(os.path.join(ctx.book.directory, "OEBPS", "content.opf")) as f:
|
||||
content = f.read()
|
||||
assert "chapter1.xhtml" in content
|
||||
|
||||
|
||||
def test_write_contents_includes_series_metadata(ctx):
|
||||
ctx.book.series.name = "My Series"
|
||||
ctx.book.series.number = "1"
|
||||
write_structure(ctx, overwrite=False)
|
||||
write_contents(ctx)
|
||||
with open(os.path.join(ctx.book.directory, "OEBPS", "content.opf")) as f:
|
||||
content = f.read()
|
||||
assert "My Series" in content
|
||||
assert "calibre:series" in content
|
||||
|
||||
|
||||
def test_write_contents_includes_illustrations_when_images_present(ctx):
|
||||
ctx.book.images.append(Image(name="photo.jpg", type="jpeg", caption="caption"))
|
||||
write_structure(ctx, overwrite=False)
|
||||
with patch("epubmaker.writer.copy"):
|
||||
write_contents(ctx)
|
||||
with open(os.path.join(ctx.book.directory, "OEBPS", "content.opf")) as f:
|
||||
content = f.read()
|
||||
assert "illustrations.xhtml" in content
|
||||
Reference in New Issue
Block a user