Improve API

This commit is contained in:
Sina Atalay
2025-02-08 15:50:01 -05:00
parent 5c69b04c83
commit c6428adcd8
8 changed files with 700 additions and 87 deletions

View File

@@ -5,9 +5,41 @@ you to version-control your CV/resume as source code.
__version__ = "2.1"
from .api import create_contents_of_a_typst_file
from .api import (
create_a_markdown_file_from_a_python_dictionary,
create_a_markdown_file_from_a_yaml_string,
create_a_pdf_from_a_python_dictionary,
create_a_pdf_from_a_yaml_string,
create_a_typst_file_from_a_python_dictionary,
create_a_typst_file_from_a_yaml_string,
create_an_html_file_from_a_python_dictionary,
create_an_html_file_from_a_yaml_string,
create_contents_of_a_markdown_file_from_a_python_dictionary,
create_contents_of_a_markdown_file_from_a_yaml_string,
create_contents_of_a_typst_file_from_a_python_dictionary,
create_contents_of_a_typst_file_from_a_yaml_string,
read_a_python_dictionary_and_return_a_data_model,
read_a_yaml_string_and_return_a_data_model,
)
__all__ = ["create_contents_of_a_typst_file"]
__all__ = [
"create_a_markdown_file_from_a_python_dictionary",
"create_a_markdown_file_from_a_python_dictionary",
"create_a_markdown_file_from_a_yaml_string",
"create_a_pdf_from_a_python_dictionary",
"create_a_pdf_from_a_yaml_string",
"create_a_typst_file_from_a_python_dictionary",
"create_a_typst_file_from_a_yaml_string",
"create_an_html_file_from_a_python_dictionary",
"create_an_html_file_from_a_yaml_string",
"create_contents_of_a_markdown_file_from_a_python_dictionary",
"create_contents_of_a_markdown_file_from_a_yaml_string",
"create_contents_of_a_typst_file_from_a_python_dictionary",
"create_contents_of_a_typst_file_from_a_python_dictionary",
"create_contents_of_a_typst_file_from_a_yaml_string",
"read_a_python_dictionary_and_return_a_data_model",
"read_a_yaml_string_and_return_a_data_model",
]
_parial_install_error_message = (
"It seems you have a partial installation of RenderCV, so this feature is"

View File

@@ -3,6 +3,36 @@ The `rendercv.api` package contains the functions to create a clean and simple A
RenderCV.
"""
from .functions import create_contents_of_a_typst_file
from .functions import (
create_a_markdown_file_from_a_python_dictionary,
create_a_markdown_file_from_a_yaml_string,
create_a_pdf_from_a_python_dictionary,
create_a_pdf_from_a_yaml_string,
create_a_typst_file_from_a_python_dictionary,
create_a_typst_file_from_a_yaml_string,
create_an_html_file_from_a_python_dictionary,
create_an_html_file_from_a_yaml_string,
create_contents_of_a_markdown_file_from_a_python_dictionary,
create_contents_of_a_markdown_file_from_a_yaml_string,
create_contents_of_a_typst_file_from_a_python_dictionary,
create_contents_of_a_typst_file_from_a_yaml_string,
read_a_python_dictionary_and_return_a_data_model,
read_a_yaml_string_and_return_a_data_model,
)
__all__ = ["create_contents_of_a_typst_file"]
__all__ = [
"create_a_markdown_file_from_a_python_dictionary",
"create_a_markdown_file_from_a_yaml_string",
"create_a_pdf_from_a_python_dictionary",
"create_a_pdf_from_a_yaml_string",
"create_a_typst_file_from_a_python_dictionary",
"create_a_typst_file_from_a_yaml_string",
"create_an_html_file_from_a_python_dictionary",
"create_an_html_file_from_a_yaml_string",
"create_contents_of_a_markdown_file_from_a_python_dictionary",
"create_contents_of_a_markdown_file_from_a_yaml_string",
"create_contents_of_a_typst_file_from_a_python_dictionary",
"create_contents_of_a_typst_file_from_a_yaml_string",
"read_a_python_dictionary_and_return_a_data_model",
"read_a_yaml_string_and_return_a_data_model",
]

View File

@@ -3,17 +3,135 @@ The `rendercv.api.functions` package contains the basic functions that are used
interact with the RenderCV.
"""
import pathlib
import shutil
import tempfile
from collections.abc import Callable
from typing import Optional
import pydantic
from .. import data, renderer
def create_contents_of_a_typst_file(
def _create_contents_of_a_something_from_something(
input: dict | str, parser: Callable, renderer: Callable
) -> str | list[dict]:
"""
Validate the input, generate a file and return it as a string. If there are any
validation errors, return them as a list of dictionaries.
Args:
input: The input file as a dictionary or a string.
parser: The parser function.
renderer: The renderer function.
Returns:
The file as a string or a list of dictionaries that contain the error messages,
locations, and the input values.
"""
try:
data_model = parser(input)
except pydantic.ValidationError as e:
if isinstance(input, str):
return data.parse_validation_errors(e, input)
return data.parse_validation_errors(e)
return renderer(data_model)
def _create_a_file_from_something(
input: dict | str,
parser: Callable,
renderer: Callable,
output_file_path: pathlib.Path,
) -> Optional[list[dict]]:
"""
Validate the input, generate a file and save it to the output file path.
Args:
input: The input file as a dictionary or a string.
parser: The parser function.
renderer: The renderer function.
output_file_path: The output file path.
Returns:
The output file path.
"""
try:
data_model = parser(input)
except pydantic.ValidationError as e:
return data.parse_validation_errors(e)
with tempfile.TemporaryDirectory() as temp_dir:
temporary_output_path = pathlib.Path(temp_dir)
typst_file = renderer(data_model, temporary_output_path)
shutil.move(typst_file, output_file_path)
return None
def read_a_python_dictionary_and_return_a_data_model(
input_file_as_a_dict: dict,
) -> data.RenderCVDataModel:
"""
Validate the input dictionary and return the data model.
Args:
input_file_as_a_dict: The input file as a dictionary.
Returns:
The data model.
"""
return data.validate_input_dictionary_and_return_the_data_model(
input_file_as_a_dict,
)
def read_a_yaml_string_and_return_a_data_model(
yaml_file_as_string: str,
) -> data.RenderCVDataModel:
"""
Validate the YAML input file given as a string and return the data model.
Args:
yaml_file_as_string: The input file as a string.
Returns:
The data model.
"""
input_file_as_a_dict = data.read_a_yaml_file(yaml_file_as_string)
return read_a_python_dictionary_and_return_a_data_model(input_file_as_a_dict)
def create_contents_of_a_typst_file_from_a_python_dictionary(
input_file_as_a_dict: dict,
) -> str | list[dict]:
"""
Validate the input dictionary, generate a Typst file and return it as a string. If
there are any validation errors, return them as a list of dictionaries.
Args:
input_file_as_a_dict: The input file as a dictionary.
Returns:
The Typst file as a string or a list of dictionaries that contain the error
messages, locations, and the input values.
"""
return _create_contents_of_a_something_from_something(
input_file_as_a_dict,
read_a_python_dictionary_and_return_a_data_model,
renderer.create_contents_of_a_typst_file,
)
def create_contents_of_a_typst_file_from_a_yaml_string(
yaml_file_as_string: str,
) -> str | list[dict]:
"""
Validate the input file given as a string, generate a Typst file and return it as a
string. If there are any validation errors, return them as a list of dictionaries.
Validate the YAML input file given as a string, generate a Typst file and return it
as a string. If there are any validation errors, return them as a list of
dictionaries.
Args:
yaml_file_as_string: The input file as a string.
@@ -22,13 +140,239 @@ def create_contents_of_a_typst_file(
The Typst file as a string or a list of dictionaries that contain the error
messages, locations, and the input values.
"""
return _create_contents_of_a_something_from_something(
yaml_file_as_string,
read_a_yaml_string_and_return_a_data_model,
renderer.create_contents_of_a_typst_file,
)
try:
input_file_as_a_dict = data.read_a_yaml_file(yaml_file_as_string)
data_model = data.validate_input_dictionary_and_return_the_data_model(
input_file_as_a_dict,
)
except pydantic.ValidationError as e:
return data.parse_validation_errors(e, yaml_file_as_string)
return renderer.create_contents_of_a_typst_file(data_model)
def create_contents_of_a_markdown_file_from_a_python_dictionary(
input_file_as_a_dict: dict,
) -> str | list[dict]:
"""
Validate the input dictionary, generate a Markdown file and return it as a string.
If there are any validation errors, return them as a list of dictionaries.
Args:
input_file_as_a_dict: The input file as a dictionary.
Returns:
The Markdown file as a string or a list of dictionaries that contain the error
messages, locations, and the input values.
"""
return _create_contents_of_a_something_from_something(
input_file_as_a_dict,
read_a_python_dictionary_and_return_a_data_model,
renderer.create_contents_of_a_markdown_file,
)
def create_contents_of_a_markdown_file_from_a_yaml_string(
yaml_file_as_string: str,
) -> str | list[dict]:
"""
Validate the input file given as a string, generate a Markdown file and return it as
a string. If there are any validation errors, return them as a list of dictionaries.
Args:
yaml_file_as_string: The input file as a string.
Returns:
The Markdown file as a string or a list of dictionaries that contain the error
messages, locations, and the input values.
"""
return _create_contents_of_a_something_from_something(
yaml_file_as_string,
read_a_yaml_string_and_return_a_data_model,
renderer.create_contents_of_a_markdown_file,
)
def create_a_typst_file_from_a_yaml_string(
yaml_file_as_string: str,
output_file_path: pathlib.Path,
) -> Optional[list[dict]]:
"""
Validate the input file given as a string, generate a Typst file and save it to the
output file path.
Args:
yaml_file_as_string: The input file as a string.
output_file_path: The output file path.
Returns:
The output file path.
"""
return _create_a_file_from_something(
yaml_file_as_string,
read_a_yaml_string_and_return_a_data_model,
renderer.create_a_typst_file,
output_file_path,
)
def create_a_typst_file_from_a_python_dictionary(
input_file_as_a_dict: dict,
output_file_path: pathlib.Path,
) -> Optional[list[dict]]:
"""
Validate the input dictionary, generate a Typst file and save it to the output file
path.
Args:
input_file_as_a_dict: The input file as a dictionary.
output_file_path: The output file path.
Returns:
The output file path.
"""
return _create_a_file_from_something(
input_file_as_a_dict,
read_a_python_dictionary_and_return_a_data_model,
renderer.create_a_typst_file,
output_file_path,
)
def create_a_markdown_file_from_a_python_dictionary(
input_file_as_a_dict: dict,
output_file_path: pathlib.Path,
) -> Optional[list[dict]]:
"""
Validate the input dictionary, generate a Markdown file and save it to the output
file path.
Args:
input_file_as_a_dict: The input file as a dictionary.
output_file_path: The output file path.
Returns:
The output file path.
"""
return _create_a_file_from_something(
input_file_as_a_dict,
read_a_python_dictionary_and_return_a_data_model,
renderer.create_a_markdown_file,
output_file_path,
)
def create_a_markdown_file_from_a_yaml_string(
yaml_file_as_string: str,
output_file_path: pathlib.Path,
) -> Optional[list[dict]]:
"""
Validate the input file given as a string, generate a Markdown file and save it to
the output file path.
Args:
yaml_file_as_string: The input file as a string.
output_file_path: The output file path.
Returns:
The output file path.
"""
return _create_a_file_from_something(
yaml_file_as_string,
read_a_yaml_string_and_return_a_data_model,
renderer.create_a_markdown_file,
output_file_path,
)
def create_an_html_file_from_a_python_dictionary(
input_file_as_a_dict: dict,
output_file_path: pathlib.Path,
) -> Optional[list[dict]]:
"""
Validate the input dictionary, generate an HTML file and save it to the output file
path.
Args:
input_file_as_a_dict: The input file as a dictionary.
output_file_path: The output file path.
Returns:
The output file path.
"""
return _create_a_file_from_something(
input_file_as_a_dict,
read_a_python_dictionary_and_return_a_data_model,
lambda x, y: renderer.render_an_html_from_markdown(
renderer.create_a_markdown_file(x, y),
),
output_file_path,
)
def create_an_html_file_from_a_yaml_string(
yaml_file_as_string: str,
output_file_path: pathlib.Path,
) -> Optional[list[dict]]:
"""
Validate the input file given as a string, generate an HTML file and save it to the
output file path.
Args:
yaml_file_as_string: The input file as a string.
output_file_path: The output file path.
Returns:
The output file path.
"""
return _create_a_file_from_something(
yaml_file_as_string,
read_a_yaml_string_and_return_a_data_model,
lambda x, y: renderer.render_an_html_from_markdown(
renderer.create_a_markdown_file(x, y),
),
output_file_path,
)
def create_a_pdf_from_a_yaml_string(
yaml_file_as_string: str,
output_file_path: pathlib.Path,
) -> Optional[list[dict]]:
"""
Validate the input file given as a string, generate a PDF file and save it to the
output file path.
Args:
yaml_file_as_string: The input file as a string.
output_file_path: The output file path.
Returns:
The output file path.
"""
return _create_a_file_from_something(
yaml_file_as_string,
read_a_yaml_string_and_return_a_data_model,
renderer.create_a_typst_file,
output_file_path,
)
def create_a_pdf_from_a_python_dictionary(
input_file_as_a_dict: dict,
output_file_path: pathlib.Path,
) -> Optional[list[dict]]:
"""
Validate the input dictionary, generate a PDF file and save it to the output file
path.
Args:
input_file_as_a_dict: The input file as a dictionary.
output_file_path: The output file path.
Returns:
The output file path.
"""
return _create_a_file_from_something(
input_file_as_a_dict,
read_a_python_dictionary_and_return_a_data_model,
renderer.create_a_typst_file,
output_file_path,
)

View File

@@ -15,6 +15,7 @@ from .renderer import (
create_a_markdown_file,
create_a_typst_file,
create_a_typst_file_and_copy_theme_files,
create_contents_of_a_markdown_file,
create_contents_of_a_typst_file,
render_a_pdf_from_typst,
render_an_html_from_markdown,
@@ -25,6 +26,7 @@ __all__ = [
"create_a_markdown_file",
"create_a_typst_file",
"create_a_typst_file_and_copy_theme_files",
"create_contents_of_a_markdown_file",
"create_contents_of_a_typst_file",
"render_a_pdf_from_typst",
"render_an_html_from_markdown",

View File

@@ -14,6 +14,43 @@ from .. import data
from . import templater
def create_a_file_name_without_extension_from_name(name: Optional[str]) -> str:
"""Create a file name from the given name by replacing the spaces with underscores
and removing typst commands.
Args:
name: The name to be converted.
Returns:
The converted name (without the extension).
"""
name_without_typst_commands = templater.remove_typst_commands(str(name))
return f"{name_without_typst_commands.replace(' ', '_')}_CV"
def create_a_file_and_write_contents_to_it(
contents: str, file_name: str, output_directory: pathlib.Path
) -> pathlib.Path:
"""Create a file with the given contents in the output directory.
Args:
contents: The contents of the file.
file_name: The name of the file.
output_directory: Path to the output directory.
Returns:
The path to the created file.
"""
# Create output directory if it doesn't exist:
if not output_directory.is_dir():
output_directory.mkdir(parents=True)
file_path = output_directory / file_name
file_path.write_text(contents, encoding="utf-8")
return file_path
def copy_theme_files_to_output_directory(
theme_name: str,
output_directory_path: pathlib.Path,
@@ -102,18 +139,37 @@ def create_a_typst_file(
typst_contents = create_contents_of_a_typst_file(rendercv_data_model)
# Create output directory if it doesn't exist:
if not output_directory.is_dir():
output_directory.mkdir(parents=True)
name_without_typst_commands = templater.remove_typst_commands(
str(rendercv_data_model.cv.name)
file_name_without_extension = create_a_file_name_without_extension_from_name(
rendercv_data_model.cv.name
)
file_name = f"{name_without_typst_commands.replace(' ', '_')}_CV.typ"
file_path = output_directory / file_name
file_path.write_text(typst_contents, encoding="utf-8")
file_name = f"{file_name_without_extension}.typ"
return file_path
return create_a_file_and_write_contents_to_it(
typst_contents,
file_name,
output_directory,
)
def create_contents_of_a_markdown_file(
rendercv_data_model: data.RenderCVDataModel,
) -> str:
"""Create a Markdown file with the given data model and return it as a string.
Args:
rendercv_data_model: The data model.
Returns:
The path to the generated Markdown file.
"""
jinja2_environment = templater.Jinja2Environment().environment
markdown_file_object = templater.MarkdownFile(
rendercv_data_model,
jinja2_environment,
)
return markdown_file_object.get_full_code()
def create_a_markdown_file(
@@ -129,21 +185,18 @@ def create_a_markdown_file(
Returns:
The path to the rendered Markdown file.
"""
# create output directory if it doesn't exist:
if not output_directory.is_dir():
output_directory.mkdir(parents=True)
markdown_contents = create_contents_of_a_markdown_file(rendercv_data_model)
jinja2_environment = templater.Jinja2Environment().environment
markdown_file_object = templater.MarkdownFile(
rendercv_data_model,
jinja2_environment,
file_name_without_extension = create_a_file_name_without_extension_from_name(
rendercv_data_model.cv.name
)
file_name = f"{file_name_without_extension}.typ"
markdown_file_name = f"{str(rendercv_data_model.cv.name).replace(' ', '_')}_CV.md"
markdown_file_path = output_directory / markdown_file_name
markdown_file_object.create_file(markdown_file_path)
return markdown_file_path
return create_a_file_and_write_contents_to_it(
markdown_contents,
file_name,
output_directory,
)
def create_a_typst_file_and_copy_theme_files(

View File

@@ -3,6 +3,7 @@
import copy
import filecmp
import itertools
import json
import pathlib
import shutil
import typing
@@ -157,6 +158,17 @@ def rendercv_data_model() -> data.RenderCVDataModel:
return data.create_a_sample_data_model()
@pytest.fixture
def rendercv_data_as_python_dictionary(
rendercv_data_model,
) -> dict:
"""Return a sample RenderCV data as a Python dictionary."""
data_model_as_json = rendercv_data_model.model_dump_json(
exclude_none=False, by_alias=True, exclude={"cv": {"sections", "photo"}}
)
return json.loads(data_model_as_json)
@pytest.fixture
def rendercv_empty_curriculum_vitae_data_model() -> data.CurriculumVitae:
"""Return an empty CurriculumVitae data model."""

View File

@@ -1,6 +1,134 @@
import pathlib
import tempfile
import rendercv
import rendercv.data
def test_create_contents_of_a_typst_file(input_file_path):
yaml_string = input_file_path.read_text()
assert isinstance(rendercv.create_contents_of_a_typst_file(yaml_string), str)
assert isinstance(
rendercv.create_contents_of_a_typst_file_from_a_yaml_string(yaml_string), str
)
def test_create_contents_of_a_typst_file_with_errors(
rendercv_data_as_python_dictionary,
):
rendercv_data_as_python_dictionary["cv"]["email"] = "invalid-email"
yaml_string = rendercv.data.generator.dictionary_to_yaml(
rendercv_data_as_python_dictionary
)
assert isinstance(
rendercv.create_contents_of_a_typst_file_from_a_yaml_string(yaml_string), list
)
def test_create_a_typst_file_from_a_yaml_string(input_file_path):
yaml_string = input_file_path.read_text()
output_file_path = pathlib.Path(tempfile.mktemp(suffix=".typst"))
errors = rendercv.create_a_typst_file_from_a_yaml_string(
yaml_string, output_file_path
)
assert errors is None
assert output_file_path.exists()
def test_create_a_typst_file_from_a_python_dictionary(
rendercv_data_as_python_dictionary,
):
output_file_path = pathlib.Path(tempfile.mktemp(suffix=".typst"))
errors = rendercv.create_a_typst_file_from_a_python_dictionary(
rendercv_data_as_python_dictionary, output_file_path
)
assert errors is None
assert output_file_path.exists()
def test_create_contents_of_a_markdown_file_from_a_yaml_string(input_file_path):
yaml_string = input_file_path.read_text()
result = rendercv.create_contents_of_a_markdown_file_from_a_yaml_string(yaml_string)
assert isinstance(result, str)
def test_create_contents_of_a_markdown_file_from_a_python_dictionary(
rendercv_data_as_python_dictionary,
):
result = rendercv.create_contents_of_a_markdown_file_from_a_python_dictionary(
rendercv_data_as_python_dictionary
)
assert isinstance(result, str)
def test_create_a_markdown_file_from_a_yaml_string(input_file_path):
yaml_string = input_file_path.read_text()
output_file_path = pathlib.Path(tempfile.mktemp(suffix=".md"))
errors = rendercv.create_a_markdown_file_from_a_yaml_string(
yaml_string, output_file_path
)
assert errors is None
assert output_file_path.exists()
def test_create_a_markdown_file_from_a_python_dictionary(
rendercv_data_as_python_dictionary,
):
output_file_path = pathlib.Path(tempfile.mktemp(suffix=".md"))
errors = rendercv.create_a_markdown_file_from_a_python_dictionary(
rendercv_data_as_python_dictionary, output_file_path
)
assert errors is None
assert output_file_path.exists()
def test_create_an_html_file_from_a_yaml_string(input_file_path):
yaml_string = input_file_path.read_text()
output_file_path = pathlib.Path(tempfile.mktemp(suffix=".html"))
errors = rendercv.create_an_html_file_from_a_yaml_string(
yaml_string, output_file_path
)
assert errors is None
assert output_file_path.exists()
def test_create_an_html_file_from_a_python_dictionary(
rendercv_data_as_python_dictionary,
):
output_file_path = pathlib.Path(tempfile.mktemp(suffix=".html"))
errors = rendercv.create_an_html_file_from_a_python_dictionary(
rendercv_data_as_python_dictionary, output_file_path
)
assert errors is None
assert output_file_path.exists()
def test_create_a_pdf_from_a_yaml_string(input_file_path):
yaml_string = input_file_path.read_text()
output_file_path = pathlib.Path(tempfile.mktemp(suffix=".pdf"))
errors = rendercv.create_a_pdf_from_a_yaml_string(yaml_string, output_file_path)
assert errors is None
assert output_file_path.exists()
def test_create_a_pdf_from_a_python_dictionary(rendercv_data_as_python_dictionary):
output_file_path = pathlib.Path(tempfile.mktemp(suffix=".pdf"))
errors = rendercv.create_a_pdf_from_a_python_dictionary(
rendercv_data_as_python_dictionary, output_file_path
)
assert errors is None
assert output_file_path.exists()
def test_read_a_python_dictionary_and_return_a_data_model(
rendercv_data_as_python_dictionary,
):
result = rendercv.read_a_python_dictionary_and_return_a_data_model(
rendercv_data_as_python_dictionary
)
assert isinstance(result, rendercv.data.RenderCVDataModel)
def test_read_a_yaml_string_and_return_a_data_model(input_file_path):
yaml_string = input_file_path.read_text()
result = rendercv.read_a_yaml_string_and_return_a_data_model(yaml_string)
assert isinstance(result, rendercv.data.RenderCVDataModel)

View File

@@ -895,81 +895,93 @@ def test_make_keywords_bold_in_a_string():
def test_bold_keywords():
data_model = data.RenderCVDataModel(
cv=data.CurriculumVitae(
name="John Doe",
sections={
"test": [
"test_keyword_1",
],
data_model_as_dict = {
"cv": {
"sections": {
"test": ["test_keyword_1"],
"test2": [
data.EducationEntry(
institution="Test Institution",
area="Test Area",
highlights=["test_keyword_2"],
summary="test_keyword_3 test_keyword_4",
),
{
"institution": "Test Institution",
"area": "Test Area",
"degree": None,
"date": None,
"start_date": None,
"end_date": None,
"location": None,
"summary": "test_keyword_3 test_keyword_4",
"highlights": ["test_keyword_2"],
}
],
"test3": [
data.ExperienceEntry(
company="Test Company",
position="Test Position",
highlights=["test_keyword_5", "test_keyword_6"],
summary="test_keyword_6 test_keyword_7",
),
{
"company": "Test Company",
"position": "Test Position",
"date": None,
"start_date": None,
"end_date": None,
"location": None,
"summary": "test_keyword_6 test_keyword_7",
"highlights": ["test_keyword_5", "test_keyword_6"],
}
],
"test4": [
data.NormalEntry(
name="Test",
highlights=["test_keyword_2"],
summary="test_keyword_3 test_keyword_4",
),
],
"test5": [
data.PublicationEntry(
title="Test Institution",
authors=["Test Author"],
),
],
"test6": [
data.BulletEntry(
bullet="test_keyword_3 test_keyword_4",
),
{
"name": "Test",
"date": None,
"start_date": None,
"end_date": None,
"location": None,
"summary": "test_keyword_3 test_keyword_4",
"highlights": ["test_keyword_2"],
}
],
"test6": [{"bullet": "test_keyword_3 test_keyword_4"}],
"test7": [
data.OneLineEntry(
label="Test Institution",
details="test_keyword_3 test_keyword_4",
),
{
"label": "Test Institution",
"details": "test_keyword_3 test_keyword_4",
}
],
},
)
},
"rendercv_settings": {
"bold_keywords": [
"test_keyword_1",
"test_keyword_2",
"test_keyword_3",
"test_keyword_4",
"test_keyword_5",
"test_keyword_6",
"test_keyword_7",
],
},
}
data_model = data.validate_input_dictionary_and_return_the_data_model(
data_model_as_dict
)
for section in data_model.cv.sections:
for entry in section.entries:
if section.title == "test":
if section.title == "Test":
assert "**test_keyword_1**" in entry
elif section.title == "test2":
elif section.title == "Test2":
assert "**test_keyword_2**" in entry.highlights[0]
assert "**test_keyword_3**" in entry.summary
assert "**test_keyword_4**" in entry.summary
elif section.title == "test3":
elif section.title == "Test3":
assert "**test_keyword_5**" in entry.highlights[0]
assert "**test_keyword_6**" in entry.highlights[1]
assert "**test_keyword_6**" in entry.summary
assert "**test_keyword_7**" in entry.summary
elif section.title == "test4":
elif section.title == "Test4":
assert "**test_keyword_2**" in entry.highlights[0]
assert "**test_keyword_3**" in entry.summary
assert "**test_keyword_4**" in entry.summary
elif section.title == "test5":
assert "**test_keyword_3**" in entry.summary
assert "**test_keyword_4**" in entry.summary
elif section.title == "test6":
elif section.title == "Test6":
assert "**test_keyword_3**" in entry.bullet
assert "**test_keyword_4**" in entry.bullet
elif section.title == "test7":
elif section.title == "Test7":
assert "**test_keyword_3**" in entry.details
assert "**test_keyword_4**" in entry.details