85 lines
3.6 KiB
Python
85 lines
3.6 KiB
Python
from types import SimpleNamespace
|
|
|
|
from wordarr.naming import render_template, sanitize
|
|
|
|
|
|
def req(**kw):
|
|
base = dict(title="", authors="", year=None, series="", volume=None)
|
|
base.update(kw)
|
|
return SimpleNamespace(**base)
|
|
|
|
|
|
def test_sanitize_keeps_special_chars_but_strips_separators():
|
|
assert sanitize("Die drei ???") == "Die drei ???"
|
|
assert sanitize("a/b\\c") == "abc"
|
|
assert "\x01" not in sanitize("a\x01b")
|
|
|
|
|
|
def test_ebook_template():
|
|
r = req(title="The Hobbit", authors="J.R.R. Tolkien", year=1937)
|
|
assert render_template("{Author}/{Title} ({Year})", r) == "J.R.R. Tolkien/The Hobbit (1937)"
|
|
|
|
|
|
def test_missing_year_drops_parens():
|
|
r = req(title="The Hobbit", authors="Tolkien")
|
|
assert render_template("{Title} ({Year})", r) == "The Hobbit"
|
|
|
|
|
|
def test_comic_template():
|
|
r = req(title="One Piece", series="One Piece", volume=3)
|
|
assert render_template("{Series}/{Series} - Band {Volume}", r) == "One Piece/One Piece - Band 03"
|
|
|
|
|
|
def test_first_author_only():
|
|
r = req(title="X", authors="Alice A, Bob B")
|
|
assert render_template("{Author}", r) == "Alice A"
|
|
|
|
|
|
def test_empty_series_level_is_dropped():
|
|
r = req(title="Der Ickabog", authors="J.K. Rowling")
|
|
assert render_template("{Author}/{Series}/{Title} ({Narrator})", r) == "J.K. Rowling/Der Ickabog"
|
|
|
|
|
|
def test_series_level_kept_when_set():
|
|
r = req(title="Harry Potter und der Feuerkelch", authors="J.K. Rowling",
|
|
series="Harry Potter")
|
|
r.narrator = "Rufus Beck"
|
|
assert render_template("{Author}/{Series}/{Title} ({Narrator})", r) == \
|
|
"J.K. Rowling/Harry Potter/Harry Potter und der Feuerkelch (Rufus Beck)"
|
|
|
|
|
|
def test_missing_values_do_not_leave_dangling_separators():
|
|
"""A "{Series}/{Volume} - {Title}" library still has standalone titles."""
|
|
req = SimpleNamespace(title="Ein Einzeltitel", authors="Jemand", series="",
|
|
volume=None, year=None, narrator="")
|
|
assert render_template("{Series}/{Volume} - {Title}", req) == "Ein Einzeltitel"
|
|
assert render_template("{Volume} - {Title} ({Year})", req) == "Ein Einzeltitel"
|
|
|
|
numbered = SimpleNamespace(title="Die Höllenbrut", authors="A. F. Morland",
|
|
series="Tony Ballard", volume=1, year=2020, narrator="")
|
|
assert render_template("{Series}/{Volume} - {Title}", numbered) == \
|
|
"Tony Ballard/01 - Die Höllenbrut"
|
|
|
|
|
|
def test_narrator_uses_the_first_name_only():
|
|
"""Two editions of one book differ by narrator; a full cast must not blow up
|
|
the folder name."""
|
|
fry = SimpleNamespace(title="Philosopher's Stone", authors="J.K. Rowling",
|
|
series="Harry Potter", volume=1, year=None,
|
|
narrator="Stephen Fry")
|
|
cast = SimpleNamespace(title="Philosopher's Stone", authors="J.K. Rowling",
|
|
series="Harry Potter", volume=1, year=None,
|
|
narrator="Hugh Laurie, Matthew Macfadyen, Riz Ahmed, Michelle Gomez")
|
|
template = "{Series}/{Volume} - {Title} ({Narrator})"
|
|
assert render_template(template, fry) == "Harry Potter/01 - Philosopher's Stone (Stephen Fry)"
|
|
assert render_template(template, cast) == "Harry Potter/01 - Philosopher's Stone (Hugh Laurie)"
|
|
# the full list stays available
|
|
assert render_template("{Narrators}", cast) == \
|
|
"Hugh Laurie, Matthew Macfadyen, Riz Ahmed, Michelle Gomez"
|
|
|
|
|
|
def test_narrator_missing_leaves_no_empty_brackets():
|
|
req = SimpleNamespace(title="Ein Buch", authors="Jemand", series="", volume=None,
|
|
year=None, narrator="")
|
|
assert render_template("{Series}/{Volume} - {Title} ({Narrator})", req) == "Ein Buch"
|