diff --git a/README.md b/README.md index 33c0486..0a9578e 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,8 @@ The application allows you to automate the process of generating a bibliography Supported citation styles: - ГОСТ Р 7.0.5-2008 +- APA +- MLA ## Installation @@ -53,10 +55,18 @@ to fill it without changing the original template: 5. Now it is possible to run the command inside the Docker container as usual, passing needed arguments to the console application: + For GOST: ```shell docker compose run app python main.py --citation gost --path_input /media/input.xlsx --path_output /media/output.docx ``` - + For APA: + ```shell + docker compose run app python main.py --citation apa --path_input /media/input.xlsx --path_output /media/output.docx + ``` + For MLA: + ```shell + docker compose run app python main.py --citation mla --path_input /media/input.xlsx --path_output /media/output.docx + ``` Also, it is possible to omit the arguments to use their defaults: ```shell docker compose run app python main.py diff --git a/src/formatters/base.py b/src/formatters/base.py index 2dc3ca3..cb711a2 100644 --- a/src/formatters/base.py +++ b/src/formatters/base.py @@ -32,4 +32,4 @@ def format(self) -> list[BaseCitationStyle]: logger.info("Общее форматирование ...") - return sorted(self.formatted_items, key=lambda item: item.formatted) + return sorted(self.formatted_items, key=lambda item: item.formatted, reverse=False) diff --git a/src/formatters/models.py b/src/formatters/models.py index c9236ca..ff1a0d4 100644 --- a/src/formatters/models.py +++ b/src/formatters/models.py @@ -20,7 +20,7 @@ class BookModel(BaseModel): city="СПб.", publishing_house="Просвещение", year=2020, - pages=999, + pages=999hjrj, ) """ @@ -42,7 +42,7 @@ class InternetResourceModel(BaseModel): InternetResourceModel( article="Наука как искусство", website="Ведомости", - link="https://www.vedomosti.ru/", + link="https://www.vedomosti.ru", access_date="01.01.2021", ) """ @@ -78,3 +78,53 @@ class ArticlesCollectionModel(BaseModel): publishing_house: str year: int = Field(..., gt=0) pages: str + + +class DissertationModel(BaseModel): + """ + Модель диссертации: + + .. code-block:: + + DissertationModel( + author="Иванов И.М.", + title="Наука как искусство", + publisher_status="д-р. / канд.", + branch_of_sciences="экон.", + speciality_code="01.01.01", + city="СПб.", + year=2020, + pages=199, + ) + """ + author: str + title: str + publisher_status: str + branch_of_sciences: str + speciality_code: str + city: str + year: int = Field(..., gt=0) + pages: int = Field(..., gt=0) + + +class ArticleFromTheJournalModel(BaseModel): + """ + Модель статьи из журнала: + + .. code-block:: + + ArticleFromTheJournalModel( + authors="Иванов И.М., Петров С.Н.", + article_title="Наука как искусство", + collection_title="Образование и наука", + year=2020, + number_of_journal="10", + pages="25-30", + ) + """ + authors: str + article_title: str + collection_title: str + year: int = Field(..., gt=0) + number_of_journal: str + pages: str diff --git a/src/formatters/styles/APA.py b/src/formatters/styles/APA.py new file mode 100644 index 0000000..e2b6cd9 --- /dev/null +++ b/src/formatters/styles/APA.py @@ -0,0 +1,184 @@ +""" +Стиль цитирования по APA +""" +from string import Template +from pydantic import BaseModel +from formatters.models import BookModel, InternetResourceModel, ArticlesCollectionModel, DissertationModel, ArticleFromTheJournalModel +from formatters.styles.base import BaseCitationStyle +from logger import get_logger + +logger = get_logger(__name__) + +class APABook(BaseCitationStyle): + """ + Форматирование для книг. + """ + data: BookModel + + @property + def template(self) -> Template: + return Template( + "$authors ($year). $title. ($edition с.$pages). $city: $publishing_house." + ) + + def substitute(self) -> str: + logger.info('Форматирование книги "%s" ...', self.data.title) + return self.template.substitute( + authors=self.data.authors, + title=self.data.title, + edition=self.get_edition(), + city=self.data.city, + publishing_house=self.data.publishing_house, + year=self.data.year, + pages=self.data.pages, + ) + + def get_edition(self) -> str: + """ + Получение отформатированной информации об издательстве. + + :return: Информация об издательстве. + """ + + return f"{self.data.edition} изд." if self.data.edition else "" + + +class APAInternetResource(BaseCitationStyle): + """ + Форматирование для интернет-ресурсов. + """ + data: InternetResourceModel + + @property + def template(self) -> Template: + return Template( + "$website. ($access_date). $article. Получено из $link" + ) + + def substitute(self) -> str: + + logger.info('Форматирование интернет-ресурса "%s" ...', self.data.article) + + return self.template.substitute( + article=self.data.article, + website=self.data.website, + link=self.data.link, + access_date=self.data.access_date, + ) + + +class APACollectionArticle(BaseCitationStyle): + """ + Форматирование для статьи из сборника. + """ + + data: ArticlesCollectionModel + + @property + def template(self) -> Template: + return Template( + "$authors ($year). $article_title. $collection_title,$pages." + ) + + def substitute(self) -> str: + + logger.info('Форматирование сборника статей "%s" ...', self.data.article_title) + + return self.template.substitute( + authors=self.data.authors, + article_title=self.data.article_title, + collection_title=self.data.collection_title, + city=self.data.city, + publishing_house=self.data.publishing_house, + year=self.data.year, + pages=self.data.pages, + ) + + +class APADissertation(BaseCitationStyle): + """ + Форматирование для диссертации. + """ + data: DissertationModel + + @property + def template(self) -> Template: + return Template( + "$author ($year). $title. $publisher_status $branch_of_sciences наук. $city" + ) + + def substitute(self) -> str: + logger.info('Форматирование диссертаций "%s" ...', self.data.title) + + return self.template.substitute( + author=self.data.author, + title=self.data.title, + publisher_status=self.data.publisher_status, + branch_of_sciences=self.data.branch_of_sciences, + speciality_code=self.data.speciality_code, + city=self.data.city, + year=self.data.year, + pages=self.data.pages, + ) + + + +class APAArticleFromTheJournal(BaseCitationStyle): + """ + Форматирование для статьи из журнала. + """ + data: ArticleFromTheJournalModel + + @property + def template(self) -> Template: + return Template( + "$authors ($year). $article_title. $collection_title, ($number_of_journal), $pages." + ) + + def substitute(self) -> str: + logger.info('Форматирование статьи из журнала "%s"...', self.data.article_title) + + return self.template.substitute( + authors=self.data.authors, + article_title=self.data.article_title, + collection_title=self.data.collection_title, + year=self.data.year, + number_of_journal=self.data.number_of_journal, + pages=self.data.pages, + ) + + +class APACitationFormatter: + """ + Базовый класс для итогового форматирования списка источников. + """ + + formatters_map = { + BookModel.__name__: APABook, + InternetResourceModel.__name__: APAInternetResource, + ArticlesCollectionModel.__name__: APACollectionArticle, + DissertationModel.__name__: APADissertation, + ArticleFromTheJournalModel.__name__: APAArticleFromTheJournal, + } + + def __init__(self, models: list[BaseModel]) -> None: + """ + Конструктор. + + :param models: Список объектов для форматирования + """ + + formatted_items = [] + for model in models: + formatted_items.append(self.formatters_map.get(type(model).__name__)(model)) # type: ignore + + self.formatted_items = formatted_items + + def format(self) -> list[BaseCitationStyle]: + """ + Форматирование списка источников. + + :return: + """ + + return sorted(self.formatted_items, key=lambda item: item.formatted) \ No newline at end of file diff --git a/src/formatters/styles/MLA.py b/src/formatters/styles/MLA.py new file mode 100644 index 0000000..5c3bce8 --- /dev/null +++ b/src/formatters/styles/MLA.py @@ -0,0 +1,183 @@ +""" +Стиль цитирования по MLA +""" +from string import Template +from pydantic import BaseModel +from formatters.models import BookModel, InternetResourceModel, ArticlesCollectionModel, DissertationModel, ArticleFromTheJournalModel +from formatters.styles.base import BaseCitationStyle +from logger import get_logger + +logger = get_logger(__name__) + +class MLABook(BaseCitationStyle): + """ + Форматирование для книг. + """ + data: BookModel + + @property + def template(self) -> Template: + return Template( + "$authors. $title. $edition, $city: $publishing_house, $year" + ) + + def substitute(self) -> str: + logger.info('Форматирование книги "%s" ...', self.data.title) + return self.template.substitute( + authors=self.data.authors, + title=self.data.title, + edition=self.get_edition(), + city=self.data.city, + publishing_house=self.data.publishing_house, + year=self.data.year, + pages=self.data.pages, + ) + + def get_edition(self) -> str: + """ + Получение отформатированной информации об издательстве. + + :return: Информация об издательстве. + """ + + return f"{self.data.edition} изд." if self.data.edition else "" + + +class MLAInternetResource(BaseCitationStyle): + """ + Форматирование для интернет-ресурсов. + """ + data: InternetResourceModel + + @property + def template(self) -> Template: + return Template( + "$article. $website, $access_date, $link" + ) + + def substitute(self) -> str: + + logger.info('Форматирование интернет-ресурса "%s" ...', self.data.article) + + return self.template.substitute( + article=self.data.article, + website=self.data.website, + link=self.data.link, + access_date=self.data.access_date, + ) + + +class MLACollectionArticle(BaseCitationStyle): + """ + Форматирование для статьи из сборника. + """ + + data: ArticlesCollectionModel + + @property + def template(self) -> Template: + return Template( + "$authors. $article_title. $collection_title. $city, $publishing_house, $year, с.$pages." + ) + + def substitute(self) -> str: + + logger.info('Форматирование сборника статей "%s" ...', self.data.article_title) + + return self.template.substitute( + authors=self.data.authors, + article_title=self.data.article_title, + collection_title=self.data.collection_title, + city=self.data.city, + publishing_house=self.data.publishing_house, + year=self.data.year, + pages=self.data.pages, + ) + + +class MLADissertation(BaseCitationStyle): + """ + Форматирование для диссертации. + """ + data: DissertationModel + + @property + def template(self) -> Template: + return Template( + "$author. $title.$year. $city. $publisher_status $branch_of_sciences наук." + ) + + def substitute(self) -> str: + logger.info('Форматирование диссертаций "%s" ...', self.data.title) + + return self.template.substitute( + author=self.data.author, + title=self.data.title, + publisher_status=self.data.publisher_status, + branch_of_sciences=self.data.branch_of_sciences, + speciality_code=self.data.speciality_code, + city=self.data.city, + year=self.data.year, + pages=self.data.pages, + ) + + +class MLAArticleFromTheJournal(BaseCitationStyle): + """ + Форматирование для статьи из журнала. + """ + data: ArticleFromTheJournalModel + + @property + def template(self) -> Template: + return Template( + "$authors. $article_title. $collection_title,($number_of_journal),$year,с.$pages." + ) + + def substitute(self) -> str: + logger.info('Форматирование статьи из журнала "%s"...', self.data.article_title) + + return self.template.substitute( + authors=self.data.authors, + article_title=self.data.article_title, + collection_title=self.data.collection_title, + year=self.data.year, + number_of_journal=self.data.number_of_journal, + pages=self.data.pages, + ) + + +class MLACitationFormatter: + """ + Базовый класс для итогового форматирования списка источников. + """ + + formatters_map = { + BookModel.__name__: MLABook, + InternetResourceModel.__name__: MLAInternetResource, + ArticlesCollectionModel.__name__: MLACollectionArticle, + DissertationModel.__name__: MLADissertation, + ArticleFromTheJournalModel.__name__: MLAArticleFromTheJournal, + } + + def __init__(self, models: list[BaseModel]) -> None: + """ + Конструктор. + + :param models: Список объектов для форматирования + """ + + formatted_items = [] + for model in models: + formatted_items.append(self.formatters_map.get(type(model).__name__)(model)) # type: ignore + + self.formatted_items = formatted_items + + def format(self) -> list[BaseCitationStyle]: + """ + Форматирование списка источников. + + :return: + """ + + return sorted(self.formatted_items, key=lambda item: item.formatted) \ No newline at end of file diff --git a/src/formatters/styles/base.py b/src/formatters/styles/base.py index 95a11a9..00e2ad7 100644 --- a/src/formatters/styles/base.py +++ b/src/formatters/styles/base.py @@ -4,7 +4,6 @@ from abc import ABC, abstractmethod from string import Template - from pydantic import BaseModel diff --git a/src/formatters/styles/gost.py b/src/formatters/styles/gost.py index b237f8a..c64cbd4 100644 --- a/src/formatters/styles/gost.py +++ b/src/formatters/styles/gost.py @@ -5,7 +5,7 @@ from pydantic import BaseModel -from formatters.models import BookModel, InternetResourceModel, ArticlesCollectionModel +from formatters.models import BookModel, InternetResourceModel, ArticlesCollectionModel, DissertationModel, ArticleFromTheJournalModel from formatters.styles.base import BaseCitationStyle from logger import get_logger @@ -47,7 +47,7 @@ def get_edition(self) -> str: :return: Информация об издательстве. """ - return f"{self.data.edition} изд. – " if self.data.edition else "" + return f"{self.data.edition} изд. " if self.data.edition else "" class GOSTInternetResource(BaseCitationStyle): @@ -103,6 +103,62 @@ def substitute(self) -> str: ) + +class GOSTDissertation(BaseCitationStyle): + """ + Форматирование для диссертации. + """ + data: DissertationModel + + @property + def template(self) -> Template: + return Template( + "$author $title. $publisher_status $branch_of_sciences наук, код специальности: $speciality_code. $city: $year, с. $pages." + ) + + def substitute(self) -> str: + logger.info('Форматирование диссертаций "%s" ...', self.data.title) + + return self.template.substitute( + author=self.data.author, + title=self.data.title, + publisher_status=self.data.publisher_status, + branch_of_sciences=self.data.branch_of_sciences, + speciality_code=self.data.speciality_code, + city=self.data.city, + year=self.data.year, + pages=self.data.pages, + ) + + +class GOSTArticleFromTheJournal(BaseCitationStyle): + """ + Форматирование для статьи из журнала. + """ + data: ArticleFromTheJournalModel + + @property + def template(self) -> Template: + return Template( + "$authors $article_title // $collection_title. - $year.Номер журнала: $number_of_journal - с. $pages." + ) + + def substitute(self) -> str: + logger.info('Форматирование статьи из журнала "%s"...', self.data.article_title) + + return self.template.substitute( + authors=self.data.authors, + article_title=self.data.article_title, + collection_title=self.data.collection_title, + year=self.data.year, + number_of_journal=self.data.number_of_journal, + pages=self.data.pages, + ) + + + + + class GOSTCitationFormatter: """ Базовый класс для итогового форматирования списка источников. @@ -112,6 +168,8 @@ class GOSTCitationFormatter: BookModel.__name__: GOSTBook, InternetResourceModel.__name__: GOSTInternetResource, ArticlesCollectionModel.__name__: GOSTCollectionArticle, + DissertationModel.__name__: GOSTDissertation, + ArticleFromTheJournalModel.__name__: GOSTArticleFromTheJournal, } def __init__(self, models: list[BaseModel]) -> None: diff --git a/src/readers/reader.py b/src/readers/reader.py index 9007a80..9b57f1b 100644 --- a/src/readers/reader.py +++ b/src/readers/reader.py @@ -7,7 +7,7 @@ import openpyxl from openpyxl.workbook import Workbook -from formatters.models import BookModel, InternetResourceModel, ArticlesCollectionModel +from formatters.models import BookModel, InternetResourceModel, ArticlesCollectionModel, DissertationModel, ArticleFromTheJournalModel from logger import get_logger from readers.base import BaseReader @@ -90,6 +90,56 @@ def attributes(self) -> dict: } +class DissertationReader(BaseReader): + """ + Чтение модели диссертации. + """ + @property + def model(self) -> Type[DissertationModel]: + return DissertationModel + + @property + def sheet(self) -> str: + return "Диссертация" + + @property + def attributes(self) -> dict: + return { + "author": {0: str}, + "title": {1: str}, + "publisher_status": {2: str}, + "branch_of_sciences": {3: str}, + "speciality_code": {4: str}, + "city": {5: str}, + "year": {6: int}, + "pages": {7: int}, + } + + +class ArticleFromTheJournalReader(BaseReader): + """ + Чтение модели диссертации. + """ + @property + def model(self) -> Type[ArticleFromTheJournalModel]: + return ArticleFromTheJournalModel + + @property + def sheet(self) -> str: + return "Статья из журнала" + + @property + def attributes(self) -> dict: + return { + "authors": {0: str}, + "article_title": {1: str}, + "collection_title": {2: str}, + "year": {3: int}, + "number_of_journal": {4: str}, + "pages": {5: str}, + } + + class SourcesReader: """ Чтение из источника данных. @@ -100,6 +150,8 @@ class SourcesReader: BookReader, InternetResourceReader, ArticlesCollectionReader, + DissertationReader, + ArticleFromTheJournalReader, ] def __init__(self, path: str) -> None: diff --git a/src/tests/conftest.py b/src/tests/conftest.py index ac5c9aa..2d0dca7 100644 --- a/src/tests/conftest.py +++ b/src/tests/conftest.py @@ -3,7 +3,7 @@ """ import pytest -from formatters.models import BookModel, InternetResourceModel, ArticlesCollectionModel +from formatters.models import BookModel, InternetResourceModel, ArticlesCollectionModel, DissertationModel, ArticleFromTheJournalModel @pytest.fixture @@ -58,3 +58,40 @@ def articles_collection_model_fixture() -> ArticlesCollectionModel: year=2020, pages="25-30", ) + + +@pytest.fixture +def dissertation_model_fixture() -> DissertationModel: + """ + Фикстура модели диссертации. + + :return: ArticlesCollectionModel + """ + + return DissertationModel( + author="Иванов И.М.", + title="Наука как искусство", + publisher_status="д-р. / канд.", + branch_of_sciences="экон.", + speciality_code="01.01.01", + city="СПб.", + year=2020, + pages=199, + ) + +@pytest.fixture +def article_from_the_journal_model_fixture() -> ArticleFromTheJournalModel: + """ + Фикстура модели статьи из журнала. + + :return: ArticlesCollectionModel + """ + + return ArticleFromTheJournalModel( + authors="Иванов И.М., Петров С.Н.", + article_title="Наука как искусство", + collection_title="Образование и наука", + year=2020, + number_of_journal="10", + pages="25-30", + ) \ No newline at end of file diff --git a/src/tests/formatters/test_apa.py b/src/tests/formatters/test_apa.py new file mode 100644 index 0000000..704bb32 --- /dev/null +++ b/src/tests/formatters/test_apa.py @@ -0,0 +1,132 @@ +""" +Тестирование функций оформления списка источников по APA. +""" + +from formatters.base import BaseCitationFormatter +from formatters.models import BookModel, InternetResourceModel, ArticlesCollectionModel, DissertationModel, ArticleFromTheJournalModel +from formatters.styles.APA import APABook, APAInternetResource, APACollectionArticle, APADissertation, APAArticleFromTheJournal + + +class TestAPA: + """ + Тестирование оформления списка источников согласно APA. + """ + + def test_book(self, book_model_fixture: BookModel) -> None: + """ + Тестирование форматирования книги. + + :param BookModel book_model_fixture: Фикстура модели книги + :return: + """ + + model = APABook(book_model_fixture) + + assert ( + model.formatted + == "Иванов И.М., Петров С.Н. (2020). Наука как искусство. (3-е изд. с.999). СПб.: Просвещение." + ) + + def test_internet_resource( + self, internet_resource_model_fixture: InternetResourceModel + ) -> None: + """ + Тестирование форматирования интернет-ресурса. + + :param InternetResourceModel internet_resource_model_fixture: Фикстура модели интернет-ресурса + :return: + """ + + model = APAInternetResource(internet_resource_model_fixture) + + assert ( + model.formatted + == "Ведомости. (01.01.2021). Наука как искусство. Получено из https://www.vedomosti.ru" + ) + + def test_articles_collection( + self, articles_collection_model_fixture: ArticlesCollectionModel + ) -> None: + """ + Тестирование форматирования сборника статей. + + :param ArticlesCollectionModel articles_collection_model_fixture: Фикстура модели сборника статей + :return: + """ + + model = APACollectionArticle(articles_collection_model_fixture) + + assert ( + model.formatted + == "Иванов И.М., Петров С.Н. (2020). Наука как искусство. Сборник научных трудов,25-30." + ) + + def test_dissertation( + self, dissertation_model_fixture: DissertationModel + ) -> None: + """ + Тестирование форматирования диссертации. + + :param DissertationModel dissertation_model_fixture: Фикстура модели диссертации + :return: + """ + + model = APADissertation(dissertation_model_fixture) + + assert ( + model.formatted + == "Иванов И.М. (2020). Наука как искусство. д-р. / канд. экон. наук. СПб." + ) + + def test_article_from_the_journal( + self, article_from_the_journal_model_fixture: ArticleFromTheJournalModel + ) -> None: + """ + Тестирование форматирования статьи в журнале. + + :param ArticleFromTheJournalModel article_from_the_journal_model_fixture: Фикстура модели статьи журнала + :return: + """ + + model = APAArticleFromTheJournal(article_from_the_journal_model_fixture) + + assert ( + model.formatted + == "Иванов И.М., Петров С.Н. (2020). Наука как искусство. Образование и наука, (10), 25-30." + ) + + + def test_citation_formatter( + self, + book_model_fixture: BookModel, + internet_resource_model_fixture: InternetResourceModel, + articles_collection_model_fixture: ArticlesCollectionModel, + dissertation_model_fixture: DissertationModel, + article_from_the_journal_model_fixture: ArticleFromTheJournalModel, + ) -> None: + """ + Тестирование функции итогового форматирования списка источников. + + :param BookModel book_model_fixture: Фикстура модели книги + :param InternetResourceModel internet_resource_model_fixture: Фикстура модели интернет-ресурса + :param ArticlesCollectionModel articles_collection_model_fixture: Фикстура модели сборника статей + :param DissertationModel dissertation_model_fixture: Фикстура модели диссертации + :param ArticleFromTheJournalModel article_from_the_journal_model_fixture: Фикстура модели статьи журнала + :return: + """ + + models = [ + APABook(book_model_fixture), + APAInternetResource(internet_resource_model_fixture), + APACollectionArticle(articles_collection_model_fixture), + APADissertation(dissertation_model_fixture), + APAArticleFromTheJournal(article_from_the_journal_model_fixture), + ] + result = BaseCitationFormatter(models).format() + + # тестирование сортировки списка источников + assert result[0] == models[1] + assert result[1] == models[3] + assert result[2] == models[0] + assert result[3] == models[4] + assert result[4] == models[2] \ No newline at end of file diff --git a/src/tests/formatters/test_gost.py b/src/tests/formatters/test_gost.py index c93e1e7..ef73dc7 100644 --- a/src/tests/formatters/test_gost.py +++ b/src/tests/formatters/test_gost.py @@ -3,8 +3,8 @@ """ from formatters.base import BaseCitationFormatter -from formatters.models import BookModel, InternetResourceModel, ArticlesCollectionModel -from formatters.styles.gost import GOSTBook, GOSTInternetResource, GOSTCollectionArticle +from formatters.models import BookModel, InternetResourceModel, ArticlesCollectionModel, DissertationModel, ArticleFromTheJournalModel +from formatters.styles.gost import GOSTBook, GOSTInternetResource, GOSTCollectionArticle, GOSTDissertation, GOSTArticleFromTheJournal class TestGOST: @@ -24,7 +24,7 @@ def test_book(self, book_model_fixture: BookModel) -> None: assert ( model.formatted - == "Иванов И.М., Петров С.Н. Наука как искусство. – 3-е изд. – СПб.: Просвещение, 2020. – 999 с." + == "Иванов И.М., Петров С.Н. Наука как искусство. – 3-е изд. СПб.: Просвещение, 2020. – 999 с." ) def test_internet_resource( @@ -61,11 +61,47 @@ def test_articles_collection( == "Иванов И.М., Петров С.Н. Наука как искусство // Сборник научных трудов. – СПб.: АСТ, 2020. – С. 25-30." ) + def test_dissertation( + self, dissertation_model_fixture: DissertationModel + ) -> None: + """ + Тестирование форматирования диссертации. + + :param DissertationModel dissertation_model_fixture: Фикстура модели диссертации + :return: + """ + + model = GOSTDissertation(dissertation_model_fixture) + + assert ( + model.formatted + == "Иванов И.М. Наука как искусство. д-р. / канд. экон. наук, код специальности: 01.01.01. СПб.: 2020, с. 199." + ) + + def test_article_from_the_journal( + self, article_from_the_journal_model_fixture: ArticleFromTheJournalModel + ) -> None: + """ + Тестирование форматирования статьи в журнале. + + :param ArticleFromTheJournalModel article_from_the_journal_model_fixture: Фикстура модели статьи журнала + :return: + """ + + model = GOSTArticleFromTheJournal(article_from_the_journal_model_fixture) + + assert ( + model.formatted + == "Иванов И.М., Петров С.Н. Наука как искусство // Образование и наука. - 2020.Номер журнала: 10 - с. 25-30." + ) + def test_citation_formatter( self, book_model_fixture: BookModel, internet_resource_model_fixture: InternetResourceModel, articles_collection_model_fixture: ArticlesCollectionModel, + dissertation_model_fixture: DissertationModel, + article_from_the_journal_model_fixture: ArticleFromTheJournalModel, ) -> None: """ Тестирование функции итогового форматирования списка источников. @@ -73,6 +109,8 @@ def test_citation_formatter( :param BookModel book_model_fixture: Фикстура модели книги :param InternetResourceModel internet_resource_model_fixture: Фикстура модели интернет-ресурса :param ArticlesCollectionModel articles_collection_model_fixture: Фикстура модели сборника статей + :param DissertationModel dissertation_model_fixture: Фикстура модели диссертации + :param ArticleFromTheJournalModel article_from_the_journal_model_fixture: Фикстура модели статьи журнала :return: """ @@ -80,10 +118,15 @@ def test_citation_formatter( GOSTBook(book_model_fixture), GOSTInternetResource(internet_resource_model_fixture), GOSTCollectionArticle(articles_collection_model_fixture), + GOSTDissertation(dissertation_model_fixture), + GOSTArticleFromTheJournal(article_from_the_journal_model_fixture), ] result = BaseCitationFormatter(models).format() - + # тестирование сортировки списка источников - assert result[0] == models[2] - assert result[1] == models[0] - assert result[2] == models[1] + assert result[0] == models[3] + assert result[1] == models[4] + assert result[2] == models[2] + assert result[3] == models[0] + assert result[4] == models[1] + \ No newline at end of file diff --git a/src/tests/formatters/test_mla.py b/src/tests/formatters/test_mla.py new file mode 100644 index 0000000..5ee0577 --- /dev/null +++ b/src/tests/formatters/test_mla.py @@ -0,0 +1,130 @@ +""" +Тестирование функций оформления списка источников по MLA. +""" + +from formatters.base import BaseCitationFormatter +from formatters.models import BookModel, InternetResourceModel, ArticlesCollectionModel, DissertationModel, ArticleFromTheJournalModel +from formatters.styles.MLA import MLABook, MLAInternetResource, MLACollectionArticle, MLADissertation, MLAArticleFromTheJournal + +class TestMLA: + """ + Тестирование оформления списка источников согласно MLA. + """ + + def test_book(self, book_model_fixture: BookModel) -> None: + """ + Тестирование форматирования книги. + + :param BookModel book_model_fixture: Фикстура модели книги + :return: + """ + + model = MLABook(book_model_fixture) + + assert ( + model.formatted + == "Иванов И.М., Петров С.Н.. Наука как искусство. 3-е изд., СПб.: Просвещение, 2020" + ) + + def test_internet_resource( + self, internet_resource_model_fixture: InternetResourceModel + ) -> None: + """ + Тестирование форматирования интернет-ресурса. + + :param InternetResourceModel internet_resource_model_fixture: Фикстура модели интернет-ресурса + :return: + """ + + model = MLAInternetResource(internet_resource_model_fixture) + + assert ( + model.formatted + == "Наука как искусство. Ведомости, 01.01.2021, https://www.vedomosti.ru" + ) + + def test_articles_collection( + self, articles_collection_model_fixture: ArticlesCollectionModel + ) -> None: + """ + Тестирование форматирования сборника статей. + + :param ArticlesCollectionModel articles_collection_model_fixture: Фикстура модели сборника статей + :return: + """ + + model = MLACollectionArticle(articles_collection_model_fixture) + + assert ( + model.formatted + == "Иванов И.М., Петров С.Н.. Наука как искусство. Сборник научных трудов. СПб., АСТ, 2020, с.25-30." + ) + + def test_dissertation( + self, dissertation_model_fixture: DissertationModel + ) -> None: + """ + Тестирование форматирования диссертации. + + :param DissertationModel dissertation_model_fixture: Фикстура модели диссертации + :return: + """ + + model = MLADissertation(dissertation_model_fixture) + + assert ( + model.formatted + == "Иванов И.М.. Наука как искусство.2020. СПб.. д-р. / канд. экон. наук." + ) + + def test_article_from_the_journal( + self, article_from_the_journal_model_fixture: ArticleFromTheJournalModel + ) -> None: + """ + Тестирование форматирования статьи в журнале. + + :param ArticleFromTheJournalModel article_from_the_journal_model_fixture: Фикстура модели статьи журнала + :return: + """ + + model = MLAArticleFromTheJournal(article_from_the_journal_model_fixture) + + assert ( + model.formatted + == "Иванов И.М., Петров С.Н.. Наука как искусство. Образование и наука,(10),2020,с.25-30." + ) + + def test_citation_formatter( + self, + book_model_fixture: BookModel, + internet_resource_model_fixture: InternetResourceModel, + articles_collection_model_fixture: ArticlesCollectionModel, + dissertation_model_fixture: DissertationModel, + article_from_the_journal_model_fixture: ArticleFromTheJournalModel, + ) -> None: + """ + Тестирование функции итогового форматирования списка источников. + + :param BookModel book_model_fixture: Фикстура модели книги + :param InternetResourceModel internet_resource_model_fixture: Фикстура модели интернет-ресурса + :param ArticlesCollectionModel articles_collection_model_fixture: Фикстура модели сборника статей + :param DissertationModel dissertation_model_fixture: Фикстура модели диссертации + :param ArticleFromTheJournalModel article_from_the_journal_model_fixture: Фикстура модели статьи журнала + :return: + """ + + models = [ + MLABook(book_model_fixture), + MLAInternetResource(internet_resource_model_fixture), + MLACollectionArticle(articles_collection_model_fixture), + MLADissertation(dissertation_model_fixture), + MLAArticleFromTheJournal(article_from_the_journal_model_fixture), + ] + result = BaseCitationFormatter(models).format() + + # тестирование сортировки списка источников + assert result[0] == models[0] + assert result[1] == models[4] + assert result[2] == models[2] + assert result[3] == models[3] + assert result[4] == models[1] \ No newline at end of file diff --git a/src/tests/readers/test_readers.py b/src/tests/readers/test_readers.py index 67d863b..5f73cb3 100644 --- a/src/tests/readers/test_readers.py +++ b/src/tests/readers/test_readers.py @@ -5,12 +5,14 @@ import pytest -from formatters.models import BookModel, InternetResourceModel, ArticlesCollectionModel +from formatters.models import BookModel, InternetResourceModel, ArticlesCollectionModel, DissertationModel, ArticleFromTheJournalModel from readers.reader import ( BookReader, SourcesReader, InternetResourceReader, ArticlesCollectionReader, + DissertationReader, + ArticleFromTheJournalReader, ) from settings import TEMPLATE_FILE_PATH @@ -104,6 +106,63 @@ def test_articles_collection(self, workbook: Any) -> None: # проверка общего количества атрибутов assert len(model_type.schema().get("properties", {}).keys()) == 7 + + def test_dissertation(self, workbook: Any) -> None: + """ + Тестирование чтения диссертации. + + :param workbook: Объект тестовой рабочей книги. + """ + + models = DissertationReader(workbook).read() + + assert len(models) == 1 + model = models[0] + + model_type = DissertationModel + + assert isinstance(model, model_type) + assert model.author == "Иванов И.М." + assert model.title == "Наука как искусство" + assert model.publisher_status == "д-р. / канд." + assert model.branch_of_sciences == "экон." + assert model.speciality_code == "01.01.01" + assert model.city == "СПб." + assert model.year == 2020 + assert model.pages == 199 + + # проверка общего количества атрибутов + assert len(model_type.schema().get("properties", {}).keys()) == 8 + + + + def test_article_journal(self, workbook: Any) -> None: + """ + Тестирование чтения журнальной статьи. + + :param workbook: Объект тестовой рабочей книги. + """ + models = ArticleFromTheJournalReader(workbook).read() + + assert len(models) == 1 + model = models[0] + + model_type = ArticleFromTheJournalModel + + assert isinstance(model, model_type) + assert model.authors == "Иванов И.М., Петров С.Н." + assert model.article_title == "Наука как искусство" + assert model.collection_title == "Образование и наука" + assert model.year == 2020 + assert model.number_of_journal == "10" + assert model.pages == "25-30" + + # проверка общего количества атрибутов + assert len(model_type.schema().get("properties", {}).keys()) == 6 + + + + def test_sources_reader(self) -> None: """ Тестирование функции чтения всех моделей из источника. @@ -111,7 +170,7 @@ def test_sources_reader(self) -> None: models = SourcesReader(TEMPLATE_FILE_PATH).read() # проверка общего считанного количества моделей - assert len(models) == 8 + assert len(models) == 10 # проверка наличия всех ожидаемых типов моделей среди типов считанных моделей model_types = {model.__class__.__name__ for model in models} @@ -119,4 +178,6 @@ def test_sources_reader(self) -> None: BookModel.__name__, InternetResourceModel.__name__, ArticlesCollectionModel.__name__, + DissertationModel.__name__, + ArticleFromTheJournalModel.__name__, }