From 0dfe12904039af1e55b9443cfdb88b29008e9de0 Mon Sep 17 00:00:00 2001 From: Sina Atalay <79940989+sinaatalay@users.noreply.github.com> Date: Wed, 10 Dec 2025 00:59:06 +0300 Subject: [PATCH] Increase test coverage --- justfile | 12 ++-- tests/cli/render_command/test_run_rendercv.py | 6 ++ tests/schema/models/test_path.py | 10 +++ .../test_variant_pydantic_model_generator.py | 62 +++++++++++++++++++ 4 files changed, 84 insertions(+), 6 deletions(-) diff --git a/justfile b/justfile index cb1c039d..8d881711 100644 --- a/justfile +++ b/justfile @@ -11,14 +11,14 @@ format: uv run --frozen ruff format src tests format-file target: - uv run --frozen --all-extras --group dev black {{target}} - uv run --frozen --all-extras --group dev ruff check --fix {{target}} - uv run --frozen --all-extras --group dev ruff format {{target}} + uv run --frozen --all-extras black {{target}} + uv run --frozen --all-extras ruff check --fix {{target}} + uv run --frozen --all-extras ruff format {{target}} check: - uv run --frozen --all-extras --group dev ruff check src tests - uv run --frozen --all-extras --group dev pyright src tests - uv run --frozen --all-extras --group dev pre-commit run --all-files + uv run --frozen --all-extras ruff check src tests + uv run --frozen --all-extras pyright src tests + uv run --frozen --all-extras pre-commit run --all-files # Testing: test: diff --git a/tests/cli/render_command/test_run_rendercv.py b/tests/cli/render_command/test_run_rendercv.py index 041d70a1..fae59763 100644 --- a/tests/cli/render_command/test_run_rendercv.py +++ b/tests/cli/render_command/test_run_rendercv.py @@ -127,3 +127,9 @@ design: run_rendercv(yaml_file, progress) assert exc_info.value.exit_code == 1 + + def test_user_error(self, tmp_path): + yaml_file = tmp_path / "doesnt_exist.yaml" + progress = ProgressPanel(quiet=True) + with pytest.raises(typer.Exit) as _, progress: + run_rendercv(yaml_file, progress) diff --git a/tests/schema/models/test_path.py b/tests/schema/models/test_path.py index 99b6008e..d7214807 100644 --- a/tests/schema/models/test_path.py +++ b/tests/schema/models/test_path.py @@ -98,6 +98,16 @@ class TestExistingInputRelativePath: assert result == existing_file + def test_existing_path_is_not_a_file_raises_error( + self, tmp_path, context_with_input_file + ): + new_dir = tmp_path / "new_dir" + new_dir.mkdir() + with pytest.raises(pydantic.ValidationError, match="is not a file"): + existing_input_relative_path_adapter.validate_python( + new_dir, context=context_with_input_file + ) + class TestPlannedInputRelativePath: def test_absolute_path_to_existing_file( diff --git a/tests/schema/test_variant_pydantic_model_generator.py b/tests/schema/test_variant_pydantic_model_generator.py index 2af05b03..ddd278fe 100644 --- a/tests/schema/test_variant_pydantic_model_generator.py +++ b/tests/schema/test_variant_pydantic_model_generator.py @@ -7,6 +7,7 @@ from rendercv.exception import RenderCVInternalError from rendercv.schema.variant_pydantic_model_generator import ( create_discriminator_field_spec, create_nested_field_spec, + create_nested_model_variant_model, create_simple_field_spec, create_variant_pydantic_model, deep_merge_nested_object, @@ -360,6 +361,25 @@ class TestCreateNestedFieldSpec: assert instance.field2 == "b" assert instance.field3 == "c" + def test_plain_dict_field_without_pydantic_model(self): + """Test that plain dict fields (non-Pydantic) are handled correctly.""" + + class ModelWithPlainDict(pydantic.BaseModel): + metadata: dict[str, Any] = pydantic.Field( + default={}, description="Plain dict field", title="Metadata" + ) + + field_info = ModelWithPlainDict.model_fields["metadata"] + updates = {"key1": "value1", "key2": "value2"} + + annotation, field = create_nested_field_spec(updates, field_info) + + # Should use the dict directly since no Pydantic model is found + assert field.default == updates + assert field.description == "Plain dict field" + assert field.title == "Metadata" + assert annotation == dict[str, Any] + @pytest.mark.parametrize( ("field_name", "new_value", "expected_annotation"), @@ -1005,3 +1025,45 @@ class TestUpdateDescriptionWithNewDefault: def test_with_none_description(self): updated = update_description_with_new_default(None, "old", "new") assert updated is None + + +class TestCreateNestedModelVariantModel: + def test_skips_fields_not_in_base_model(self): + """Test that fields not in base model are skipped during nested variant creation.""" + + class Nested(pydantic.BaseModel): + x: int = 1 + y: int = 2 + + class Outer(pydantic.BaseModel): + nested: Nested = Nested() + + # Pass updates that include a field not in Nested's definition + updates = {"x": 100, "nonexistent_field": "should_be_skipped"} + + variant_class = create_nested_model_variant_model(Nested, updates) + + # The variant should be created without errors + instance = variant_class() + assert instance.x == 100 # pyright: ignore[reportAttributeAccessIssue] + assert instance.y == 2 # pyright: ignore[reportAttributeAccessIssue] + # nonexistent_field should not be in the instance + assert not hasattr(instance, "nonexistent_field") + + def test_plain_dict_field_treated_as_simple_value(self): + """Test that plain dict fields are treated as simple values in nested model variants.""" + + class ModelWithPlainDict(pydantic.BaseModel): + metadata: dict[str, str] = {"default_key": "default_value"} + count: int = 1 + + updates = { + "metadata": {"new_key": "new_value"}, + "count": 10, + } + + variant_class = create_nested_model_variant_model(ModelWithPlainDict, updates) + + instance = variant_class() + assert instance.metadata == {"new_key": "new_value"} # pyright: ignore[reportAttributeAccessIssue] + assert instance.count == 10 # pyright: ignore[reportAttributeAccessIssue]