mirror of
https://github.com/rendercv/rendercv.git
synced 2026-04-17 21:39:00 -04:00
- Update hypothesis to latest version (>=6.151.9) - Remove pythonpath pytest config (was only needed for tests.strategies) - Consolidate classic_theme.py into single file with all design models - Move Hypothesis strategies from strategies.py into their test files - Add noqa: ARG001 to unused yaml_field_override CLI parameter - Fix lint and type errors across the codebase
146 lines
5.0 KiB
Python
146 lines
5.0 KiB
Python
import pydantic
|
|
import pytest
|
|
from hypothesis import given, settings
|
|
from hypothesis import strategies as st
|
|
|
|
# They are called dynamically in the test with `eval(f"{entry_type}(**entry)")`.
|
|
from rendercv.schema.models.cv.entries.bullet import BulletEntry # NOQA: F401
|
|
from rendercv.schema.models.cv.entries.education import EducationEntry # NOQA: F401
|
|
from rendercv.schema.models.cv.entries.experience import ExperienceEntry # NOQA: F401
|
|
from rendercv.schema.models.cv.entries.normal import NormalEntry # NOQA: F401
|
|
from rendercv.schema.models.cv.entries.one_line import OneLineEntry # NOQA: F401
|
|
from rendercv.schema.models.cv.entries.publication import PublicationEntry # NOQA: F401
|
|
from rendercv.schema.models.cv.section import (
|
|
Section,
|
|
available_entry_models,
|
|
dictionary_key_to_proper_section_title,
|
|
get_entry_type_name_and_section_model,
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("entry", "expected_entry_type", "expected_section_type"),
|
|
[
|
|
(
|
|
"publication_entry",
|
|
"PublicationEntry",
|
|
"SectionWithPublicationEntries",
|
|
),
|
|
(
|
|
"experience_entry",
|
|
"ExperienceEntry",
|
|
"SectionWithExperienceEntries",
|
|
),
|
|
(
|
|
"education_entry",
|
|
"EducationEntry",
|
|
"SectionWithEducationEntries",
|
|
),
|
|
(
|
|
"normal_entry",
|
|
"NormalEntry",
|
|
"SectionWithNormalEntries",
|
|
),
|
|
("one_line_entry", "OneLineEntry", "SectionWithOneLineEntries"),
|
|
("text_entry", "TextEntry", "SectionWithTextEntries"),
|
|
("bullet_entry", "BulletEntry", "SectionWithBulletEntries"),
|
|
],
|
|
)
|
|
def test_get_entry_type_name_and_section_model(
|
|
entry, expected_entry_type, expected_section_type, request: pytest.FixtureRequest
|
|
):
|
|
entry = request.getfixturevalue(entry)
|
|
entry_type, SectionModel = get_entry_type_name_and_section_model(entry)
|
|
assert entry_type == expected_entry_type
|
|
assert SectionModel.__name__ == expected_section_type
|
|
|
|
# Initialize the entry with the entry type to test with model instances too
|
|
if entry_type != "TextEntry":
|
|
entry = eval(f"{entry_type}(**entry)")
|
|
entry_type, SectionModel = get_entry_type_name_and_section_model(entry)
|
|
assert entry_type == expected_entry_type
|
|
assert SectionModel.__name__ == expected_section_type
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"EntryType",
|
|
available_entry_models,
|
|
)
|
|
def test_entries_with_extra_attributes(EntryType, request: pytest.FixtureRequest):
|
|
# Get the name of the class:
|
|
entry_type_name: str = EntryType.__name__
|
|
|
|
# Convert from camel case to snake case
|
|
entry_type_name = "".join(
|
|
["_" + c.lower() if c.isupper() else c for c in entry_type_name]
|
|
).lstrip("_")
|
|
|
|
# Get entry contents from fixture:
|
|
entry_contents = request.getfixturevalue(entry_type_name)
|
|
|
|
entry_contents["extra_attribute"] = "extra value"
|
|
|
|
entry = EntryType(**entry_contents)
|
|
|
|
assert entry.extra_attribute == "extra value"
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("key", "expected_section_title"),
|
|
[
|
|
("this_is_a_test", "This Is a Test"),
|
|
("welcome_to_rendercv!", "Welcome to Rendercv!"),
|
|
("Welcome to RenderCV!", "Welcome to RenderCV!"),
|
|
("\\faGraduationCap_education", "\\faGraduationCap_education"),
|
|
("\\faGraduationCap Education", "\\faGraduationCap Education"),
|
|
("Hello_World", "Hello_World"),
|
|
("Hello World", "Hello World"),
|
|
],
|
|
)
|
|
def test_dictionary_key_to_proper_section_title(key, expected_section_title):
|
|
assert dictionary_key_to_proper_section_title(key) == expected_section_title
|
|
|
|
|
|
class TestDictionaryKeyToProperSectionTitle:
|
|
@settings(deadline=None)
|
|
@given(
|
|
key=st.from_regex(r"[a-z]{1,5}(_[a-z]{1,5}){0,3}", fullmatch=True),
|
|
)
|
|
def test_snake_case_replaces_underscores_with_spaces(self, key: str) -> None:
|
|
result = dictionary_key_to_proper_section_title(key)
|
|
assert "_" not in result
|
|
assert " " in result or len(key.split("_")) == 1
|
|
|
|
@settings(deadline=None)
|
|
@given(
|
|
parts=st.lists(
|
|
st.from_regex(r"[a-zA-Z0-9]{1,10}", fullmatch=True),
|
|
min_size=2,
|
|
max_size=5,
|
|
)
|
|
)
|
|
def test_keys_with_spaces_returned_unchanged(self, parts: list[str]) -> None:
|
|
key = " ".join(parts)
|
|
assert dictionary_key_to_proper_section_title(key) == key
|
|
|
|
@settings(deadline=None)
|
|
@given(
|
|
key=st.from_regex(r"[a-zA-Z]*[A-Z][a-zA-Z]*", fullmatch=True).filter(
|
|
lambda s: " " not in s and len(s) <= 30
|
|
)
|
|
)
|
|
def test_keys_with_uppercase_returned_unchanged(self, key: str) -> None:
|
|
assert dictionary_key_to_proper_section_title(key) == key
|
|
|
|
|
|
def test_section_rejects_none_entries():
|
|
section_adapter = pydantic.TypeAdapter[Section](Section)
|
|
with pytest.raises(pydantic.ValidationError):
|
|
section_adapter.validate_python([None])
|
|
|
|
|
|
def test_section_accepts_empty_list():
|
|
section_adapter = pydantic.TypeAdapter[Section](Section)
|
|
result = section_adapter.validate_python([])
|
|
assert result == []
|