diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 36f2268..b15cabc 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,7 +1,7 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.4.1 + rev: v0.12.11 hooks: # Run the linter. - id: ruff diff --git a/src/summarize_gutenberg/__main__.py b/src/summarize_gutenberg/__main__.py index c094cd2..50f84c7 100644 --- a/src/summarize_gutenberg/__main__.py +++ b/src/summarize_gutenberg/__main__.py @@ -1,3 +1,3 @@ from summarize_gutenberg.cli import app -app() \ No newline at end of file +app() diff --git a/src/summarize_gutenberg/api.py b/src/summarize_gutenberg/api.py index d7788ce..aef51f2 100644 --- a/src/summarize_gutenberg/api.py +++ b/src/summarize_gutenberg/api.py @@ -4,6 +4,7 @@ from summarize_gutenberg.db import DB + @dataclass class Book: id: int = field(default=None) @@ -15,11 +16,11 @@ class Book: @classmethod def from_dict(cls, d): return Book(**d) + def to_dict(self): return asdict(self) - class BooksDB: def __init__(self, db_path): self._db_path = db_path @@ -37,7 +38,7 @@ def get_book(self, book_id: int) -> Book: if db_item is not None: return Book.from_dict(db_item) # else: - # raise InvalidBookId(book_id) + # raise InvalidBookId(book_id) def list_books(self): """Return a list of books.""" @@ -59,7 +60,7 @@ def delete_book(self, book_id: int) -> None: """Remove a book from db with given book_id.""" self._db.delete(book_id) # except KeyError as exc: - # raise InvalidBookId(book_id) from exc + # raise InvalidBookId(book_id) from exc def delete_all(self) -> None: """Remove all books from db.""" @@ -69,4 +70,4 @@ def close(self): self._db.close() def path(self): - return self._db_path \ No newline at end of file + return self._db_path diff --git a/src/summarize_gutenberg/cli.py b/src/summarize_gutenberg/cli.py index 1e9fe32..d7c7b6f 100644 --- a/src/summarize_gutenberg/cli.py +++ b/src/summarize_gutenberg/cli.py @@ -1,7 +1,7 @@ import os import typer from rich import print, box -from rich.prompt import Prompt, IntPrompt, Confirm +from rich.prompt import Prompt, IntPrompt from rich.table import Table from pathlib import Path from contextlib import contextmanager @@ -14,11 +14,13 @@ FILE_DIR = Path("./files/") SUMMARY_DIR = FILE_DIR / "summaries" + def dir_check(): """Make sure the directories for saving files exist""" FILE_DIR.mkdir(parents=True, exist_ok=True) SUMMARY_DIR.mkdir(parents=True, exist_ok=True) + dir_check() app = typer.Typer() @@ -33,7 +35,8 @@ def get_default_books(): for book in books: with books_db() as db: db.add_book(Book.from_dict(books[book])) - + + @app.command() def default(): """ @@ -47,19 +50,19 @@ def default(): get_default_books() table = Table(box=box.SQUARE_DOUBLE_HEAD, border_style="magenta") - table.add_column('No.') - table.add_column('[bold cyan]Title', max_width=75, no_wrap=False) - table.add_column('[bold magenta]Author') - table.add_column('[bold yellow]Fulltext URL') + table.add_column("No.") + table.add_column("[bold cyan]Title", max_width=75, no_wrap=False) + table.add_column("[bold magenta]Author") + table.add_column("[bold yellow]Fulltext URL") with books_db() as db: books = db.list_books() for order_num, book in enumerate(books, start=1): - table.add_row(f'{str(order_num)}.', book.title, book.author, f"[yellow]{book.url}") + table.add_row(f"{str(order_num)}.", book.title, book.author, f"[yellow]{book.url}") order_num += 1 - print('\n') + print("\n") print(table) - print('\n') + print("\n") max_choice = len(books) choice = Prompt.ask("Select a book by number") @@ -67,8 +70,10 @@ def default(): choice = Prompt.ask("[red]Please choose a number between 1 and 32") selected_book = books[int(choice) - 1] - - print(f"\nYou have chosen [bold cyan]{selected_book.title}[/bold cyan] by [bold magenta]{selected_book.author}[/bold magenta].") + + print( + f"\nYou have chosen [bold cyan]{selected_book.title}[/bold cyan] by [bold magenta]{selected_book.author}[/bold magenta]." + ) filepath = FILE_DIR / Path(selected_book.filename) if filepath.exists(): @@ -78,23 +83,24 @@ def default(): write_text_to_file(selected_book.url, filepath) print(f"\nText of {selected_book.title} saved to {filepath}.") - choice = Prompt.ask("\nDo you want to [P]rint or [S]ave your summary?", choices=['p', 's']) + choice = Prompt.ask("\nDo you want to [P]rint or [S]ave your summary?", choices=["p", "s"]) chunks = IntPrompt.ask("How many lines per chunk?", default=400) # if chunks < 50: # print("[red bold]Warning[/red bold]: choosing a low value could take a lot of time and resources.") # confirmation = Confirm.ask("Are you sure?") - - if choice == 'p': + + if choice == "p": print_summary(filepath, chunks) else: target_filepath = SUMMARY_DIR / Path(selected_book.filename) save_summary(filepath, target_filepath, chunks) - print(f'\nSummary saved to {target_filepath}.') + print(f"\nSummary saved to {target_filepath}.") with books_db() as db: db.delete_all() + def get_path(): db_path_env = os.getenv("BOOKS_DB_DIR", "") if db_path_env: @@ -103,6 +109,7 @@ def get_path(): db_path = Path(__file__).parent / "books_db" return db_path + @contextmanager def books_db(): db_path = get_path() @@ -111,5 +118,3 @@ def books_db(): yield db finally: db.close() - - diff --git a/src/summarize_gutenberg/db.py b/src/summarize_gutenberg/db.py index acaac3b..6a101b9 100644 --- a/src/summarize_gutenberg/db.py +++ b/src/summarize_gutenberg/db.py @@ -3,9 +3,7 @@ class DB: def __init__(self, db_path, db_file_prefix): - self._db = tinydb.TinyDB( - db_path / f"{db_file_prefix}.json", create_dirs=True - ) + self._db = tinydb.TinyDB(db_path / f"{db_file_prefix}.json", create_dirs=True) def create(self, item: dict) -> int: id = self._db.insert(item) diff --git a/src/summarize_gutenberg/get_books.py b/src/summarize_gutenberg/get_books.py index 5ae2b53..133c23e 100644 --- a/src/summarize_gutenberg/get_books.py +++ b/src/summarize_gutenberg/get_books.py @@ -75,13 +75,14 @@ def url_check(formats): return url + def create_filename(title): """ Create a filename for the book from a shortened version of its title. """ res_list = [] - colons = {':', ';'} - puncts = {',', ' ', '.', '—', '-', "'", '"'} + colons = {":", ";"} + puncts = {",", " ", ".", "—", "-", "'", '"'} for char in title: if char in colons: @@ -90,10 +91,11 @@ def create_filename(title): continue else: res_list.append(char.lower()) - - res_list.append('.txt') - return ''.join(res_list) + res_list.append(".txt") + + return "".join(res_list) + def fetch_default_books(): """ @@ -123,7 +125,7 @@ def fetch_default_books(): def process_books(books): - """ + """ Create a dictionary of fetched books where the key is a sequential number and the value is a dictionary of book info. """ book_data = {} @@ -148,9 +150,10 @@ def process_books(books): return book_data + if __name__ == "__main__": - books = process_books(fetch_default_books()) + books = process_books(fetch_default_books()) book_list = [book for book in books] for book in book_list: - print(books[book]['filename']) + print(books[book]["filename"]) diff --git a/src/summarize_gutenberg/get_text.py b/src/summarize_gutenberg/get_text.py index 245f59d..3c08ec6 100644 --- a/src/summarize_gutenberg/get_text.py +++ b/src/summarize_gutenberg/get_text.py @@ -112,6 +112,7 @@ def is_valid_utf8(byte_sequence): except UnicodeDecodeError: return False + def strip_headers(text): lines = text.splitlines() sep = os.linesep @@ -159,6 +160,7 @@ def strip_headers(text): return str(sep.join(out), encoding="utf-8") + def write_text_to_file(url, file_path): text_request = requests.get(url, stream=True) @@ -168,7 +170,7 @@ def write_text_to_file(url, file_path): text_content = text_request.content cleaned_text = strip_headers(text_content) - with open(file_path, "w", encoding='utf-8') as file: + with open(file_path, "w", encoding="utf-8") as file: file.write(cleaned_text) - return file_path \ No newline at end of file + return file_path diff --git a/src/summarize_gutenberg/make_summary.py b/src/summarize_gutenberg/make_summary.py index 0f4d396..77ecb05 100644 --- a/src/summarize_gutenberg/make_summary.py +++ b/src/summarize_gutenberg/make_summary.py @@ -3,18 +3,20 @@ tokenizer = AutoTokenizer.from_pretrained("pszemraj/pegasus-x-large-book-summary") model = AutoModelForSeq2SeqLM.from_pretrained("pszemraj/pegasus-x-large-book-summary") + def read_in_chunks(filepath, chunk_size=800): - with open(filepath, 'r', encoding='utf-8') as file: - current_chunk = [] - for line in file: - cleaned_line = line.strip() - current_chunk.append(cleaned_line) - if len(current_chunk) == chunk_size: - yield current_chunk - current_chunk = [] - - if current_chunk: + with open(filepath, "r", encoding="utf-8") as file: + current_chunk = [] + for line in file: + cleaned_line = line.strip() + current_chunk.append(cleaned_line) + if len(current_chunk) == chunk_size: yield current_chunk + current_chunk = [] + + if current_chunk: + yield current_chunk + def make_summary(chunk): inputs = tokenizer.encode(chunk, return_tensors="pt", truncation=True) @@ -25,13 +27,12 @@ def make_summary(chunk): return summary - def save_summary(source, target, chunk_size): - with open(target,'w') as target: + with open(target, "w") as target: for chunk in read_in_chunks(source, chunk_size=chunk_size): - target.write(make_summary(' '.join(chunk))) + target.write(make_summary(" ".join(chunk))) + def print_summary(source, chunk_size): for chunk in read_in_chunks(source, chunk_size=chunk_size): - print(make_summary(' '.join(chunk))) - + print(make_summary(" ".join(chunk))) diff --git a/tests/conftest.py b/tests/conftest.py index 25b48d2..552e55f 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -6,6 +6,7 @@ from summarize_gutenberg.api import Book + @pytest.fixture() def book_fixture(): """ @@ -19,4 +20,4 @@ def book_fixture(): filename="yesterdaystomorrows.txt", ) - return book \ No newline at end of file + return book diff --git a/tests/test_author_parse.py b/tests/test_author_parse.py index be38ee6..6979e0c 100644 --- a/tests/test_author_parse.py +++ b/tests/test_author_parse.py @@ -2,20 +2,24 @@ from summarize_gutenberg.get_books import author_parse authors = [ -('Aristotle', 'Aristotle'), # single name -('Austen, Jane', 'Jane Austen'), # first & last -('Stevenson, Robert Louis', 'Robert Louis Stevenson'), # first last middle -('Chesterton, G. K. (Gilbert Keith)', 'G. K. Chesterton'), # parenthetical -('H. D. (Hilda Doolittle)', 'H. D.'), # irregular parenthetical -('Tolkien, J. R. R. (John Ronald Reuel)', 'J. R. R. Tolkien'), # parenthetical with three initials -('Von Arnim, Elizabeth', 'Elizabeth Von Arnim'), # von -('Sanchez, Nellie Van de Grift', 'Nellie Van de Grift Sanchez'), # van -('Martinez de la Torre, Rafael', 'Rafael Martinez de la Torre'), # de la -('Cervantes Saavedra, Miguel de', 'Miguel de Cervantes Saavedra'), # de -('Alger, Horatio, Jr.', 'Horatio Alger Jr.'), # jr -(None, '') # none + ("Aristotle", "Aristotle"), # single name + ("Austen, Jane", "Jane Austen"), # first & last + ("Stevenson, Robert Louis", "Robert Louis Stevenson"), # first last middle + ("Chesterton, G. K. (Gilbert Keith)", "G. K. Chesterton"), # parenthetical + ("H. D. (Hilda Doolittle)", "H. D."), # irregular parenthetical + ( + "Tolkien, J. R. R. (John Ronald Reuel)", + "J. R. R. Tolkien", + ), # parenthetical with three initials + ("Von Arnim, Elizabeth", "Elizabeth Von Arnim"), # von + ("Sanchez, Nellie Van de Grift", "Nellie Van de Grift Sanchez"), # van + ("Martinez de la Torre, Rafael", "Rafael Martinez de la Torre"), # de la + ("Cervantes Saavedra, Miguel de", "Miguel de Cervantes Saavedra"), # de + ("Alger, Horatio, Jr.", "Horatio Alger Jr."), # jr + (None, ""), # none ] -@pytest.mark.parametrize('input, expected', authors) + +@pytest.mark.parametrize("input, expected", authors) def test_author_parse(input, expected): - assert author_parse(input) == expected, f'Expected {expected}, but got {author_parse(input)}' \ No newline at end of file + assert author_parse(input) == expected, f"Expected {expected}, but got {author_parse(input)}" diff --git a/tests/test_booksdb.py b/tests/test_booksdb.py index 00d68d3..5c803db 100644 --- a/tests/test_booksdb.py +++ b/tests/test_booksdb.py @@ -4,6 +4,7 @@ from summarize_gutenberg.api import Book, BooksDB + @pytest.fixture() def books_db(): with TemporaryDirectory() as db_dir: @@ -12,20 +13,24 @@ def books_db(): yield db db.close() + def test_empty_db(books_db): assert books_db.count() == 0 + def test_add_one_book(books_db): books_db.add_book(Book()) assert books_db.count() == 1 + def test_add_two_books(books_db): books_db.add_book(Book()) books_db.add_book(Book()) assert books_db.count() == 2 + def test_delete_book(books_db): books_db.add_book(Book(id=1)) books_db.add_book(Book(id=2)) @@ -33,6 +38,7 @@ def test_delete_book(books_db): assert books_db.count() == 1 + def test_delete_all(books_db): books_db.add_book(Book(id=1)) books_db.add_book(Book(id=2)) @@ -40,6 +46,7 @@ def test_delete_all(books_db): assert books_db.count() == 0 + def test_get_book(books_db, book_fixture): book = book_fixture books_db.add_book(book) @@ -47,6 +54,7 @@ def test_get_book(books_db, book_fixture): assert book == gotten_book + def test_list_books(books_db): books_db.add_book(Book(id=1)) books_db.add_book(Book(id=2)) @@ -58,6 +66,7 @@ def test_list_books(books_db): for book in listed_books: assert book.id in expected_ids + def test_update_book(books_db, book_fixture): book = book_fixture books_db.add_book(book) @@ -72,12 +81,8 @@ def test_update_book(books_db, book_fixture): books_db.update_book(book.id, new_book) updated_book_data = books_db.get_book(book.id).to_dict() - assert updated_book_data['id'] == book.id - assert updated_book_data['title'] == new_data['title'] - assert updated_book_data['author'] == new_data['author'] - assert updated_book_data['url'] == new_data['url'] - assert updated_book_data['filename'] == new_data['filename'] - - - - + assert updated_book_data["id"] == book.id + assert updated_book_data["title"] == new_data["title"] + assert updated_book_data["author"] == new_data["author"] + assert updated_book_data["url"] == new_data["url"] + assert updated_book_data["filename"] == new_data["filename"] diff --git a/tests/test_create_filename.py b/tests/test_create_filename.py index ba07ca5..add115b 100644 --- a/tests/test_create_filename.py +++ b/tests/test_create_filename.py @@ -2,15 +2,24 @@ from summarize_gutenberg.get_books import create_filename titles = [ - ('Dracula', 'dracula.txt'), # one word - ('Franny and Zooey', 'frannyandzooey.txt'), # spaces - ('Frankenstein; Or, The Modern Prometheus', 'frankenstein.txt'), # semicolon - ('"Left-Wing" Communism: an Infantile Disorder', 'leftwingcommunism.txt'), # colon, quoation marks, hyphen - ('We Who Are About To...', 'wewhoareaboutto.txt'), # periods - ("Swann's Way", 'swannsway.txt'), # apostrophe/single quote - ("My Life — Volume 1", 'mylifevolume1.txt') # em dash which is weird but one of the top gutenberg books has one + ("Dracula", "dracula.txt"), # one word + ("Franny and Zooey", "frannyandzooey.txt"), # spaces + ("Frankenstein; Or, The Modern Prometheus", "frankenstein.txt"), # semicolon + ( + '"Left-Wing" Communism: an Infantile Disorder', + "leftwingcommunism.txt", + ), # colon, quoation marks, hyphen + ("We Who Are About To...", "wewhoareaboutto.txt"), # periods + ("Swann's Way", "swannsway.txt"), # apostrophe/single quote + ( + "My Life — Volume 1", + "mylifevolume1.txt", + ), # em dash which is weird but one of the top gutenberg books has one ] -@pytest.mark.parametrize('input, expected', titles) + +@pytest.mark.parametrize("input, expected", titles) def test_create_filename(input, expected): - assert create_filename(input) == expected, f'Expected {expected}, but got {create_filename(input)}' \ No newline at end of file + assert create_filename(input) == expected, ( + f"Expected {expected}, but got {create_filename(input)}" + ) diff --git a/tests/test_get_books.py b/tests/test_get_books.py index f6a3a6e..78d959f 100644 --- a/tests/test_get_books.py +++ b/tests/test_get_books.py @@ -1,206 +1,212 @@ import pytest import requests -from summarize_gutenberg.get_books import fetch_default_books, process_books, author_check, url_check +from summarize_gutenberg.get_books import ( + fetch_default_books, + process_books, + author_check, + url_check, +) + def test_gutendex_api(): - base_url = 'https://gutendex.com/books?languages=en' - book_request = requests.get(base_url, params={'q': 'requests+lang:en'}) + base_url = "https://gutendex.com/books?languages=en" + book_request = requests.get(base_url, params={"q": "requests+lang:en"}) assert book_request.status_code == 200 - assert 'results' in book_request.json() - assert len(book_request.json()['results']) == 32 + assert "results" in book_request.json() + assert len(book_request.json()["results"]) == 32 + def test_fetch_default_books_success(mocker): mock_response = mocker.Mock() - mock_response.json.return_value = {'results': ['book1', 'book2']} + mock_response.json.return_value = {"results": ["book1", "book2"]} mock_response.raise_for_status.return_value = None - mocker.patch('requests.get', return_value=mock_response) + mocker.patch("requests.get", return_value=mock_response) books = fetch_default_books() - assert books == ['book1', 'book2'] + assert books == ["book1", "book2"] + def test_fetch_default_books_http_error(mocker): - mocker.patch('requests.get', side_effect=requests.exceptions.HTTPError("Http Error")) + mocker.patch("requests.get", side_effect=requests.exceptions.HTTPError("Http Error")) with pytest.raises(requests.exceptions.HTTPError): fetch_default_books() + def test_fetch_default_books_connection_error(mocker): - mocker.patch('requests.get', side_effect=requests.exceptions.ConnectionError("Connection Error")) + mocker.patch( + "requests.get", side_effect=requests.exceptions.ConnectionError("Connection Error") + ) with pytest.raises(requests.exceptions.ConnectionError): fetch_default_books() + def test_fetch_default_books_timeout(mocker): - mocker.patch('requests.get', side_effect=requests.exceptions.Timeout("Timeout Error")) + mocker.patch("requests.get", side_effect=requests.exceptions.Timeout("Timeout Error")) with pytest.raises(requests.exceptions.Timeout): fetch_default_books() + def test_fetch_default_books_request_exception(mocker): - mocker.patch('requests.get', side_effect=requests.exceptions.RequestException("Exotic Error")) + mocker.patch("requests.get", side_effect=requests.exceptions.RequestException("Exotic Error")) with pytest.raises(requests.exceptions.RequestException): fetch_default_books() -test_authors_no_list = { - 'name': 'Doe, John' -} -test_authors_no_name = [ - { - 'mame': 'Doe, John' - } - ] +test_authors_no_list = {"name": "Doe, John"} + +test_authors_no_name = [{"mame": "Doe, John"}] + def test_author_check_no_list(): with pytest.raises(KeyError) as excinfo: author_check(test_authors_no_list) assert "'authors' in unexpected format (should be list)" in str(excinfo.value) + def test_author_check_no_name(): with pytest.raises(KeyError) as excinfo: author_check(test_authors_no_name) assert "No field named 'name' in authors" in str(excinfo.value) + test_formats_no_plaintext = { - 'wrong_format': 'book_url', - } + "wrong_format": "book_url", +} + def test_url_check_no_plaintext(): with pytest.raises(KeyError) as excinfo: url_check(test_formats_no_plaintext) assert "No plaintext URL or plaintext key format has changed" in str(excinfo.value) + book_data = [ # Normal data ( { - 'id': 1, - 'title': 'Sample Book', - 'authors': [{'name': 'Doe, John'}], - 'formats': {'text/plain; charset=us-ascii': 'http://example.com'} + "id": 1, + "title": "Sample Book", + "authors": [{"name": "Doe, John"}], + "formats": {"text/plain; charset=us-ascii": "http://example.com"}, }, { 1: { - 'title': 'Sample Book', - 'author': 'John Doe', - 'url': 'http://example.com', - 'filename': 'samplebook.txt', + "title": "Sample Book", + "author": "John Doe", + "url": "http://example.com", + "filename": "samplebook.txt", } - } + }, ), # No title ( { - 'id': 1, - 'authors': [{'name': 'Doe, John'}], - 'formats': {'text/plain; charset=us-ascii': 'http://example.com'} + "id": 1, + "authors": [{"name": "Doe, John"}], + "formats": {"text/plain; charset=us-ascii": "http://example.com"}, }, { 1: { - 'title': None, - 'author': 'John Doe', - 'url': 'http://example.com', - 'filename': None, + "title": None, + "author": "John Doe", + "url": "http://example.com", + "filename": None, } - } + }, ), # No author ( { - 'id': 1, - 'title': 'Sample Book', - 'formats': {'text/plain; charset=us-ascii': 'http://example.com'} + "id": 1, + "title": "Sample Book", + "formats": {"text/plain; charset=us-ascii": "http://example.com"}, }, { 1: { - 'title': 'Sample Book', - 'author': 'No author found.', - 'url': 'http://example.com', - 'filename': 'samplebook.txt', + "title": "Sample Book", + "author": "No author found.", + "url": "http://example.com", + "filename": "samplebook.txt", } - } + }, ), # No formats ( - { - 'id': 1, - 'title': 'Sample Book', - 'authors': [{'name': 'Doe, John'}] - }, + {"id": 1, "title": "Sample Book", "authors": [{"name": "Doe, John"}]}, { 1: { - 'title': 'Sample Book', - 'author': 'John Doe', - 'url': 'No URLs found.', - 'filename': 'samplebook.txt', + "title": "Sample Book", + "author": "John Doe", + "url": "No URLs found.", + "filename": "samplebook.txt", } - } + }, ), # No title or author ( - { - 'id': 1, - 'formats': {'text/plain; charset=us-ascii': 'http://example.com'} - }, + {"id": 1, "formats": {"text/plain; charset=us-ascii": "http://example.com"}}, { 1: { - 'title': None, - 'author': 'No author found.', - 'url': 'http://example.com', - 'filename': None, + "title": None, + "author": "No author found.", + "url": "http://example.com", + "filename": None, } - } + }, ), # no title or formats ( { - 'id': 1, - 'authors': [{'name': 'Doe, John'}], + "id": 1, + "authors": [{"name": "Doe, John"}], }, { 1: { - 'title': None, - 'author': 'John Doe', - 'url': 'No URLs found.', - 'filename': None, + "title": None, + "author": "John Doe", + "url": "No URLs found.", + "filename": None, } - } + }, ), # no author or formats ( { - 'id': 1, - 'title': 'Sample Book', + "id": 1, + "title": "Sample Book", }, { 1: { - 'title': 'Sample Book', - 'author': 'No author found.', - 'url': 'No URLs found.', - 'filename': 'samplebook.txt', + "title": "Sample Book", + "author": "No author found.", + "url": "No URLs found.", + "filename": "samplebook.txt", } - } + }, ), # no title author or formats ( { - 'id': 1, + "id": 1, }, { 1: { - 'title': None, - 'author': 'No author found.', - 'url': 'No URLs found.', - 'filename': None, + "title": None, + "author": "No author found.", + "url": "No URLs found.", + "filename": None, } - } + }, ), ] -@pytest.mark.parametrize('input, expected', book_data) +@pytest.mark.parametrize("input, expected", book_data) def test_process_books(input, expected): result = process_books([input]) - assert result == expected, f'Expected {expected}, but got {result}' \ No newline at end of file + assert result == expected, f"Expected {expected}, but got {result}" diff --git a/tests/test_models.py b/tests/test_models.py index 33778dd..12b5a2b 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -1,5 +1,6 @@ from summarize_gutenberg.api import Book + def test_book_field_access(book_fixture): book = book_fixture @@ -9,6 +10,7 @@ def test_book_field_access(book_fixture): assert book.url == "https://www.gutenberg.org/" assert book.filename == "yesterdaystomorrows.txt" + def test_book_defaults(): book = Book() @@ -17,6 +19,7 @@ def test_book_defaults(): assert book.url is None assert book.filename is None + def test_from_dict(book_fixture): book1 = book_fixture book2_dict = { @@ -30,10 +33,11 @@ def test_from_dict(book_fixture): assert book1 == book2 + def test_to_dict(book_fixture): book1 = book_fixture book_dict = book1.to_dict() - expected = { + expected = { "id": 1, "title": "Yesterday's Tomorrows", "author": "Wilfred Sinecure", @@ -41,4 +45,4 @@ def test_to_dict(book_fixture): "filename": "yesterdaystomorrows.txt", } - assert book_dict == expected \ No newline at end of file + assert book_dict == expected