From 340f410948b50093f99be1446748281d71b122cb Mon Sep 17 00:00:00 2001 From: Sina Atalay Date: Fri, 9 Feb 2024 20:14:46 +0100 Subject: [PATCH] improve tests --- tests/conftest.py | 47 +++++++++++++++++++++++++ tests/test_data_models.py | 74 ++++++++++++++++++++++++++++++++++++++- tests/test_renderer.py | 41 ++++++++++++++++++++-- 3 files changed, 159 insertions(+), 3 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index f28da55..c01a1e8 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,7 +1,11 @@ import pathlib +import jinja2 import pytest +from rendercv import data_models as dm +import rendercv.renderer as r + @pytest.fixture def publication_entry() -> dict[str, str | list[str]]: @@ -49,6 +53,49 @@ def text_entry() -> str: return "My Text Entry" +@pytest.fixture +def rendercv_data_model( + education_entry, + experience_entry, + normal_entry, + publication_entry, + one_line_entry, + text_entry, +) -> dm.RenderCVDataModel: + return dm.RenderCVDataModel( + cv=dm.CurriculumVitae( + name="John Doe", + sections={ + "Section 1": [ + dm.NormalEntry(**normal_entry), + ], + "Section 2": [ + dm.OneLineEntry(**one_line_entry), + dm.OneLineEntry(**one_line_entry), + dm.OneLineEntry(**one_line_entry), + dm.OneLineEntry(**one_line_entry), + ], + "Section 3": [ + dm.PublicationEntry(**publication_entry), + ], + "Section 4": [ + dm.ExperienceEntry(**experience_entry), + dm.ExperienceEntry(**experience_entry), + ], + "Section 5": [ + dm.EducationEntry(**education_entry), + ], + "Section 6": [text_entry], + }, + ), + ) + + +@pytest.fixture +def jinja2_environment() -> jinja2.Environment: + return r.setup_jinja2_environment() + + @pytest.fixture def tests_directory_path() -> pathlib.Path: return pathlib.Path(__file__).parent diff --git a/tests/test_data_models.py b/tests/test_data_models.py index f7fa432..81a2144 100644 --- a/tests/test_data_models.py +++ b/tests/test_data_models.py @@ -1,5 +1,6 @@ from datetime import date as Date import json +import pathlib import pydantic import pytest @@ -122,6 +123,19 @@ def test_read_input_file(input_file_path): assert isinstance(data_model, dm.RenderCVDataModel) +@pytest.mark.parametrize( + "input_file_name", + [ + "invalid", + "invalid_extension.txt", + ], +) +def test_read_input_file_invalid_path(input_file_name): + with pytest.raises(FileNotFoundError): + invalid_path = pathlib.Path(input_file_name) + dm.read_input_file(invalid_path) + + def test_get_a_sample_data_model(): data_model = dm.get_a_sample_data_model("John Doe") assert isinstance(data_model, dm.RenderCVDataModel) @@ -167,6 +181,7 @@ def test_if_the_schema_is_the_latest(root_directory_path): ("2020", "2021", None, "2020 to 2021", "1 year"), ("2020", None, None, "2020 to present", "4 years"), ("2020-10-10", "2022", None, "Oct. 2020 to 2022", "2 years"), + ("2020-10-10", "2020-11-05", None, "Oct. 2020 to Nov. 2020", "1 month"), ("2022", "2023-10-10", None, "2022 to Oct. 2023", "1 year"), ("2020-01-01", "present", "My Custom Date", "My Custom Date", ""), ("2020-01-01", None, "My Custom Date", "My Custom Date", ""), @@ -216,6 +231,12 @@ def test_invalid_publication_dates(publication_entry, date): ("2020-01-01", "2999-01-01", None), ("2022", "2021", None), ("2021", "2060", None), + ("2025", "2021", None), + (None, None, "2028"), + ("2020-01-01", "invalid_end_date", None), + ("invalid_start_date", "2021-01-01", None), + ("2020-99-99", "2021-01-01", None), + ("2020-10-12", "2020-99-99", None), ], ) def test_invalid_dates(start_date, end_date, date): @@ -261,6 +282,15 @@ def test_invalid_doi(publication_entry, doi): dm.PublicationEntry(**publication_entry) +@pytest.mark.parametrize( + "network, username", + [("Mastodon", "invalidmastodon"), ("invalid@invalidmastodon", "@inva@l@id")], +) +def test_invalid_social_networks(network, username): + with pytest.raises(pydantic.ValidationError): + dm.SocialNetwork(network=network, username=username) + + @pytest.mark.parametrize( "network, username, expected_url", [ @@ -277,6 +307,49 @@ def test_social_network_url(network, username, expected_url): assert str(social_network.url) == expected_url +@pytest.mark.parametrize( + "entry, expected_entry_type, expected_section_type", + [ + ( + "publication_entry", + "PublicationEntry", + dm.SectionWithPublicationEntries, + ), + ( + "experience_entry", + "ExperienceEntry", + dm.SectionWithExperienceEntries, + ), + ( + "education_entry", + "EducationEntry", + dm.SectionWithEducationEntries, + ), + ( + "normal_entry", + "NormalEntry", + dm.SectionWithNormalEntries, + ), + ("one_line_entry", "OneLineEntry", dm.SectionWithOneLineEntries), + ("text_entry", "TextEntry", dm.SectionWithTextEntries), + ], +) +def test_get_entry_and_section_type( + entry, expected_entry_type, expected_section_type, request +): + entry = request.getfixturevalue(entry) + entry_type, section_type = dm.get_entry_and_section_type(entry) + assert entry_type == expected_entry_type + assert section_type == expected_section_type + + # initialize the entry with the entry type + if not entry_type == "TextEntry": + entry = eval(f"dm.{entry_type}(**entry)") + entry_type, section_type = dm.get_entry_and_section_type(entry) + assert entry_type == expected_entry_type + assert section_type == expected_section_type + + @pytest.mark.parametrize( "title, default_entry", [ @@ -417,4 +490,3 @@ def test_sections_with_invalid_entries(section_title): }] with pytest.raises(pydantic.ValidationError): dm.CurriculumVitae(**input) - diff --git a/tests/test_renderer.py b/tests/test_renderer.py index 4854942..7056664 100644 --- a/tests/test_renderer.py +++ b/tests/test_renderer.py @@ -1,6 +1,7 @@ import math import filecmp import shutil +import pathlib import pytest import jinja2 @@ -10,6 +11,12 @@ from rendercv import renderer as r from rendercv import data_models as dm +def test_latex_file_class(tmp_path, rendercv_data_model, jinja2_environment): + latex_file = r.LaTeXFile(rendercv_data_model, jinja2_environment) + latex_file.get_latex_code() + latex_file.generate_latex_file(tmp_path / "test.tex") + + @pytest.mark.parametrize( "value, something, match_str, expected", [ @@ -128,6 +135,30 @@ def test_invalid_divide_length_by(length, divider): r.divide_length_by(length, divider) +def test_get_an_item_with_a_specific_attribute_value(): + entry_objects = [ + dm.OneLineEntry( + name="Test1", + details="Test2", + ), + dm.OneLineEntry( + name="Test3", + details="Test4", + ), + ] + result = r.get_an_item_with_a_specific_attribute_value( + entry_objects, "name", "Test3" + ) + assert result == entry_objects[1] + result = r.get_an_item_with_a_specific_attribute_value( + entry_objects, "name", "DoesntExist" + ) + assert result is None + + with pytest.raises(AttributeError): + r.get_an_item_with_a_specific_attribute_value(entry_objects, "invalid", "Test5") + + def test_setup_jinja2_environment(): env = r.setup_jinja2_environment() @@ -163,14 +194,14 @@ themes = ["classic"] @time_machine.travel("2024-01-01") def test_generate_latex_file(tmp_path, reference_files_directory_path, theme_name): file_name = f"{theme_name}_theme_CV.tex" - output_file_path = tmp_path / file_name + output_file_path = tmp_path / "make_sure_it_generates_the_directory" / file_name reference_file_path = reference_files_directory_path / file_name data_model = dm.RenderCVDataModel( cv=dm.CurriculumVitae(name=f"{theme_name} theme"), design=dm.Design(theme=theme_name), ) - r.generate_latex_file(data_model, tmp_path) + r.generate_latex_file(data_model, tmp_path / "make_sure_it_generates_the_directory") # Uncomment the line below to update the reference files: # r.generate_latex_file(data_model, reference_files_directory_path) @@ -236,3 +267,9 @@ def test_latex_to_pdf(tmp_path, reference_files_directory_path, theme_name): # ) assert filecmp.cmp(output_pdf_file_path, reference_pdf_file_path) + + +def test_latex_to_pdf_invalid_latex_file(tmp_path): + with pytest.raises(FileNotFoundError): + file_path = pathlib.Path("file_doesnt_exist.tex") + r.latex_to_pdf(file_path)