From 63d628c35491e9b6dbec8255dfe927ec6aafeb78 Mon Sep 17 00:00:00 2001 From: Mathias Date: Sat, 10 Oct 2026 12:09:37 +0100 Subject: [PATCH] tests improvements --- src/photools3/metadata_writer.py | 14 ++-- test/test_metadata_writer.py | 127 ++++++++++++++++++++++++++----- 2 files changed, 114 insertions(+), 27 deletions(-) diff --git a/src/photools3/metadata_writer.py b/src/photools3/metadata_writer.py index 9f8c318..7370838 100644 --- a/src/photools3/metadata_writer.py +++ b/src/photools3/metadata_writer.py @@ -17,14 +17,11 @@ _EXIFTOOL_MISSING_MSG = ( if shutil.which("exiftool") is None: raise FileNotFoundError(_EXIFTOOL_MISSING_MSG) -# File extensions that should use XMP sidecars -SIDECAR_EXTENSIONS = {".dng", ".nef", ".cr2", ".cr3", ".arw", ".raf", ".orf", ".rw2"} - XmpKey = Annotated[str, StringConstraints(pattern=r"^\w+\:\w+")] type Caption = str type Keywords = list[str] -type Color = str | None +type Color = int type XmpMetadata = dict[str, Any] XMP_KEYS_CAPTION: list[XmpKey] = [ @@ -41,7 +38,7 @@ XMP_KEYS_KEYWORDS: list[XmpKey] = [ def _prefixed(txt: str) -> str: - return f"{settings.metadata_prefix} {txt}" + return f"{settings.metadata_prefix}{txt}" def _is_prefixed(txt: str) -> bool: @@ -133,7 +130,7 @@ class MetadataWriter: if not include_prefix and existing_no_prefix and not override: return if include_prefix: - caption = settings.metadata_prefix.join([existing_no_prefix, f" {caption}"]) + caption = f"{existing_no_prefix}{_prefixed(caption)}" metadata_tags = {key: caption for key in XMP_KEYS_CAPTION} self.set_metadata(metadata_tags) @@ -146,14 +143,13 @@ class MetadataWriter: self.set_metadata(metadata_tags) def write_color(self, color: Color): - # TODO - ... + self.set_metadata({"XMP-darktable:Colorlabels": color}) def write( self, caption: Caption | None = None, keywords: Keywords | None = None, - color: Color = None, + color: Color | None = None, ): if caption is not None: self.write_caption(caption) diff --git a/test/test_metadata_writer.py b/test/test_metadata_writer.py index 7597d59..48f163e 100644 --- a/test/test_metadata_writer.py +++ b/test/test_metadata_writer.py @@ -37,22 +37,56 @@ def test_read_metadata(make_dng_file, pic): file_path = make_dng_file(pic) result = MetadataWriter(file_path) assert result + assert result.metadata + assert isinstance(result.metadata, dict) + + +@pytest.mark.parametrize( + "pic, expected_keywords", + [ + (PATHS_DNG_EXAMPLES[0], ["architektur", "zeit|abend"]), + (PATHS_DNG_EXAMPLES[1], ["architektur"]), + (PATHS_DNG_EXAMPLES[2], ["morgen", "tiere|vögel"]), + ( + PATHS_DNG_EXAMPLES[3], + [ + "abend", + "architektur", + "bewegungsunschärfe", + "lichter", + "mainz", + "spiegelung", + "wasser", + ], + ), + ( + PATHS_DNG_EXAMPLES[4], + ["grau", "landschaft", "landschaft|weinberge", "personen", "tiefe", "weg"], + ), + ], +) +def test_get_keywords(make_dng_file, pic, expected_keywords): + path = make_dng_file(pic) + result = MetadataWriter(path).get_keywords() + assert sorted(result) == sorted(expected_keywords) def test_prefixed(): txt = "bla_bla" txt_prefixed = _prefixed(txt) - assert txt_prefixed == "photools: bla_bla" + assert txt_prefixed == "photools|bla_bla" -def test_is_prefixed(): - txt_prefixed = "photools: some text" - txt_not_prefixed = "prefix is missing here" - txt_false_prefix = "some_perfix: but not the right one" - - assert _is_prefixed(txt_prefixed) - assert not _is_prefixed(txt_not_prefixed) - assert not _is_prefixed(txt_false_prefix) +@pytest.mark.parametrize( + "txt, expected_result", + [ + ("photools|some text", True), + ("prefix is missing here", False), + ("some_perfix|but not the right one", False), + ], +) +def test_is_prefixed(txt, expected_result): + assert _is_prefixed(txt) == expected_result @pytest.mark.parametrize("pic", PATHS_DNG_EXAMPLES) @@ -74,7 +108,7 @@ def test_set_caption(make_dng_file, pic): assert metadata_writer.sidecar_path.exists() # ... but now! result = metadata_writer.get_caption() assert result - assert result == "photools: This is a test" + assert result == "photools|This is a test" def test_set_caption_on_existing(metadata_writer_on_existing): @@ -86,32 +120,89 @@ def test_set_caption_on_existing(metadata_writer_on_existing): metadata_writer_on_existing.write_caption("Another caption") assert ( metadata_writer_on_existing.get_caption() - == "Let's pretend this is the caption of the original image. photools: Another caption" + == "Let's pretend this is the caption of the original image. photools|Another caption" ) metadata_writer_on_existing.write_caption("Updated caption") assert ( metadata_writer_on_existing.get_caption() - == "Let's pretend this is the caption of the original image. photools: Updated caption" + == "Let's pretend this is the caption of the original image. photools|Updated caption" ) metadata_writer_on_existing.write_caption("Don't do this!", override=False) assert ( metadata_writer_on_existing.get_caption() - == "Let's pretend this is the caption of the original image. photools: Updated caption" + == "Let's pretend this is the caption of the original image. photools|Updated caption" ) -@pytest.mark.parametrize("pic", PATHS_DNG_EXAMPLES) -def test_set_keywords(make_dng_file, pic): +@pytest.mark.parametrize( + "pic, expected_keywords", + [ + ( + PATHS_DNG_EXAMPLES[0], + [ + "architektur", + "zeit|abend", + "photools|hund", + "photools|katze", + "photools|maus", + ], + ), + ( + PATHS_DNG_EXAMPLES[1], + ["architektur", "photools|hund", "photools|katze", "photools|maus"], + ), + ( + PATHS_DNG_EXAMPLES[2], + [ + "morgen", + "tiere|vögel", + "photools|hund", + "photools|katze", + "photools|maus", + ], + ), + ( + PATHS_DNG_EXAMPLES[3], + [ + "abend", + "architektur", + "bewegungsunschärfe", + "lichter", + "mainz", + "spiegelung", + "wasser", + "photools|hund", + "photools|katze", + "photools|maus", + ], + ), + ( + PATHS_DNG_EXAMPLES[4], + [ + "grau", + "landschaft", + "landschaft|weinberge", + "personen", + "tiefe", + "weg", + "photools|hund", + "photools|katze", + "photools|maus", + ], + ), + ], +) +def test_set_keywords(make_dng_file, pic, expected_keywords): metadata_writer = MetadataWriter(make_dng_file(pic)) metadata_writer.write_keywords(["hund", "katze", "maus"]) result = metadata_writer.get_keywords() assert result assert isinstance(result, list) - assert "photools: hund" in result - assert "photools: katze" in result - assert "photools: maus" in result + assert "photools|hund" in result + assert "photools|katze" in result + assert "photools|maus" in result def test_set_keywords_on_existing():