Files
obsidian-metadata/tests/metadata_test.py
2023-03-20 18:15:05 -04:00

394 lines
14 KiB
Python

# type: ignore
"""Test metadata.py."""
from pathlib import Path
import pytest
from obsidian_metadata.models.enums import MetadataType
from obsidian_metadata.models.metadata import (
InlineTags,
VaultMetadata,
)
from tests.helpers import Regex, remove_ansi
FILE_CONTENT: str = Path("tests/fixtures/test_vault/test1.md").read_text()
TAG_LIST: list[str] = ["tag 1", "tag 2", "tag 3"]
METADATA: dict[str, list[str]] = {
"frontmatter_Key1": ["author name"],
"frontmatter_Key2": ["note", "article"],
"shared_key1": ["shared_key1_value"],
"shared_key2": ["shared_key2_value"],
"tags": ["tag 2", "tag 1", "tag 3"],
"top_key1": ["top_key1_value"],
"top_key2": ["top_key2_value"],
"top_key3": ["top_key3_value"],
"intext_key": ["intext_key_value"],
}
METADATA_2: dict[str, list[str]] = {"key1": ["value1"], "key2": ["value2", "value3"]}
FRONTMATTER_CONTENT: str = """
---
tags:
- tag_1
- tag_2
-
- 📅/tag_3
frontmatter_Key1: "frontmatter_Key1_value"
frontmatter_Key2: ["note", "article"]
shared_key1: "shared_key1_value"
---
more content
---
horizontal: rule
---
"""
INLINE_CONTENT = """\
repeated_key:: repeated_key_value1
#inline_tag_top1,#inline_tag_top2
**bold_key1**:: bold_key1_value
**bold_key2:: bold_key2_value**
link_key:: [[link_key_value]]
tag_key:: #tag_key_value
emoji_📅_key:: emoji_📅_key_value
**#bold_tag**
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. [in_text_key1:: in_text_key1_value] Ut enim ad minim veniam, quis nostrud exercitation [in_text_key2:: in_text_key2_value] ullamco laboris nisi ut aliquip ex ea commodo consequat. #in_text_tag Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
```python
#ffffff
# This is sample text [no_key:: value]with tags and metadata
#in_codeblock_tag1
#ffffff;
in_codeblock_key:: in_codeblock_value
The quick brown fox jumped over the #in_codeblock_tag2
```
repeated_key:: repeated_key_value2
"""
def test_inline_tags_add() -> None:
"""Test inline tags add."""
tags = InlineTags(INLINE_CONTENT)
assert tags.add("bold_tag") is False
assert tags.add("new_tag") is True
assert tags.list == [
"bold_tag",
"in_text_tag",
"inline_tag_top1",
"inline_tag_top2",
"new_tag",
"tag_key_value",
]
def test_inline_tags_contains() -> None:
"""Test inline tags contains."""
tags = InlineTags(INLINE_CONTENT)
assert tags.contains("bold_tag") is True
assert tags.contains("no tag") is False
assert tags.contains(r"\w_\w", is_regex=True) is True
assert tags.contains(r"\d_\d", is_regex=True) is False
def test_inline_tags_create() -> None:
"""Test inline tags creation."""
tags = InlineTags(FRONTMATTER_CONTENT)
tags.metadata_key
assert tags.list == []
tags = InlineTags(INLINE_CONTENT)
assert tags.list == [
"bold_tag",
"in_text_tag",
"inline_tag_top1",
"inline_tag_top2",
"tag_key_value",
]
assert tags.list_original == [
"bold_tag",
"in_text_tag",
"inline_tag_top1",
"inline_tag_top2",
"tag_key_value",
]
def test_inline_tags_delete() -> None:
"""Test inline tags delete."""
tags = InlineTags(INLINE_CONTENT)
assert tags.list == [
"bold_tag",
"in_text_tag",
"inline_tag_top1",
"inline_tag_top2",
"tag_key_value",
]
assert tags.delete("no tag") is False
assert tags.has_changes() is False
assert tags.delete("bold_tag") is True
assert tags.list == [
"in_text_tag",
"inline_tag_top1",
"inline_tag_top2",
"tag_key_value",
]
assert tags.has_changes() is True
assert tags.delete(r"\d{3}") is False
assert tags.delete(r"inline_tag_top\d") is True
assert tags.list == ["in_text_tag", "tag_key_value"]
def test_inline_tags_rename() -> None:
"""Test inline tags rename."""
tags = InlineTags(INLINE_CONTENT)
assert tags.list == [
"bold_tag",
"in_text_tag",
"inline_tag_top1",
"inline_tag_top2",
"tag_key_value",
]
assert tags.rename("no tag", "new tag") is False
assert tags.has_changes() is False
assert tags.rename("bold_tag", "new tag") is True
assert tags.list == [
"in_text_tag",
"inline_tag_top1",
"inline_tag_top2",
"new tag",
"tag_key_value",
]
assert tags.has_changes() is True
def test_vault_metadata() -> None:
"""Test VaultMetadata class."""
vm = VaultMetadata()
assert vm.dict == {}
vm.index_metadata(area=MetadataType.FRONTMATTER, metadata=METADATA)
vm.index_metadata(area=MetadataType.INLINE, metadata=METADATA_2)
vm.index_metadata(area=MetadataType.TAGS, metadata=TAG_LIST)
assert vm.dict == {
"frontmatter_Key1": ["author name"],
"frontmatter_Key2": ["article", "note"],
"intext_key": ["intext_key_value"],
"key1": ["value1"],
"key2": ["value2", "value3"],
"shared_key1": ["shared_key1_value"],
"shared_key2": ["shared_key2_value"],
"tags": ["tag 1", "tag 2", "tag 3"],
"top_key1": ["top_key1_value"],
"top_key2": ["top_key2_value"],
"top_key3": ["top_key3_value"],
}
assert vm.frontmatter == {
"frontmatter_Key1": ["author name"],
"frontmatter_Key2": ["article", "note"],
"intext_key": ["intext_key_value"],
"shared_key1": ["shared_key1_value"],
"shared_key2": ["shared_key2_value"],
"tags": ["tag 1", "tag 2", "tag 3"],
"top_key1": ["top_key1_value"],
"top_key2": ["top_key2_value"],
"top_key3": ["top_key3_value"],
}
assert vm.inline_metadata == {"key1": ["value1"], "key2": ["value2", "value3"]}
assert vm.tags == ["tag 1", "tag 2", "tag 3"]
new_metadata = {"added_key": ["added_value"], "frontmatter_Key2": ["new_value"]}
new_tags = ["tag 4", "tag 5"]
vm.index_metadata(area=MetadataType.FRONTMATTER, metadata=new_metadata)
vm.index_metadata(area=MetadataType.TAGS, metadata=new_tags)
assert vm.dict == {
"added_key": ["added_value"],
"frontmatter_Key1": ["author name"],
"frontmatter_Key2": ["article", "new_value", "note"],
"intext_key": ["intext_key_value"],
"key1": ["value1"],
"key2": ["value2", "value3"],
"shared_key1": ["shared_key1_value"],
"shared_key2": ["shared_key2_value"],
"tags": ["tag 1", "tag 2", "tag 3"],
"top_key1": ["top_key1_value"],
"top_key2": ["top_key2_value"],
"top_key3": ["top_key3_value"],
}
assert vm.frontmatter == {
"added_key": ["added_value"],
"frontmatter_Key1": ["author name"],
"frontmatter_Key2": ["article", "new_value", "note"],
"intext_key": ["intext_key_value"],
"shared_key1": ["shared_key1_value"],
"shared_key2": ["shared_key2_value"],
"tags": ["tag 1", "tag 2", "tag 3"],
"top_key1": ["top_key1_value"],
"top_key2": ["top_key2_value"],
"top_key3": ["top_key3_value"],
}
assert vm.inline_metadata == {"key1": ["value1"], "key2": ["value2", "value3"]}
assert vm.tags == ["tag 1", "tag 2", "tag 3", "tag 4", "tag 5"]
def test_vault_metadata_print(capsys) -> None:
"""Test print_metadata method."""
vm = VaultMetadata()
vm.index_metadata(area=MetadataType.FRONTMATTER, metadata=METADATA)
vm.index_metadata(area=MetadataType.INLINE, metadata=METADATA_2)
vm.index_metadata(area=MetadataType.TAGS, metadata=TAG_LIST)
vm.print_metadata(area=MetadataType.ALL)
captured = remove_ansi(capsys.readouterr().out)
assert "All metadata" in captured
assert "All inline tags" in captured
assert "┃ Keys ┃ Values ┃" in captured
assert "│ shared_key1 │ shared_key1_value │" in captured
assert captured == Regex("#tag 1 +#tag 2")
vm.print_metadata(area=MetadataType.FRONTMATTER)
captured = remove_ansi(capsys.readouterr().out)
assert "All frontmatter" in captured
assert "┃ Keys ┃ Values ┃" in captured
assert "│ shared_key1 │ shared_key1_value │" in captured
assert "value1" not in captured
vm.print_metadata(area=MetadataType.INLINE)
captured = remove_ansi(capsys.readouterr().out)
assert "All inline" in captured
assert "┃ Keys ┃ Values ┃" in captured
assert "shared_key1" not in captured
assert "│ key1 │ value1 │" in captured
vm.print_metadata(area=MetadataType.TAGS)
captured = remove_ansi(capsys.readouterr().out)
assert "All inline tags " in captured
assert "┃ Keys ┃ Values ┃" not in captured
assert captured == Regex("#tag 1 +#tag 2")
vm.print_metadata(area=MetadataType.KEYS)
captured = remove_ansi(capsys.readouterr().out)
assert "All Keys " in captured
assert "┃ Keys ┃ Values ┃" not in captured
assert captured != Regex("#tag 1 +#tag 2")
assert captured == Regex("frontmatter_Key1 +frontmatter_Key2")
def test_vault_metadata_contains() -> None:
"""Test contains method."""
vm = VaultMetadata()
vm.index_metadata(area=MetadataType.FRONTMATTER, metadata=METADATA)
vm.index_metadata(area=MetadataType.INLINE, metadata=METADATA_2)
vm.index_metadata(area=MetadataType.TAGS, metadata=TAG_LIST)
assert vm.dict == {
"frontmatter_Key1": ["author name"],
"frontmatter_Key2": ["article", "note"],
"intext_key": ["intext_key_value"],
"key1": ["value1"],
"key2": ["value2", "value3"],
"shared_key1": ["shared_key1_value"],
"shared_key2": ["shared_key2_value"],
"tags": ["tag 1", "tag 2", "tag 3"],
"top_key1": ["top_key1_value"],
"top_key2": ["top_key2_value"],
"top_key3": ["top_key3_value"],
}
assert vm.frontmatter == {
"frontmatter_Key1": ["author name"],
"frontmatter_Key2": ["article", "note"],
"intext_key": ["intext_key_value"],
"shared_key1": ["shared_key1_value"],
"shared_key2": ["shared_key2_value"],
"tags": ["tag 1", "tag 2", "tag 3"],
"top_key1": ["top_key1_value"],
"top_key2": ["top_key2_value"],
"top_key3": ["top_key3_value"],
}
assert vm.inline_metadata == {"key1": ["value1"], "key2": ["value2", "value3"]}
assert vm.tags == ["tag 1", "tag 2", "tag 3"]
with pytest.raises(ValueError):
vm.contains(area=MetadataType.ALL, value="key1")
assert vm.contains(area=MetadataType.ALL, key="no_key") is False
assert vm.contains(area=MetadataType.ALL, key="key1") is True
assert vm.contains(area=MetadataType.ALL, key="frontmatter_Key2", value="article") is True
assert vm.contains(area=MetadataType.ALL, key="frontmatter_Key2", value="none") is False
assert vm.contains(area=MetadataType.ALL, key="1$", is_regex=True) is True
assert vm.contains(area=MetadataType.ALL, key=r"\d\d", is_regex=True) is False
assert vm.contains(area=MetadataType.FRONTMATTER, key="no_key") is False
assert vm.contains(area=MetadataType.FRONTMATTER, key="frontmatter_Key1") is True
assert (
vm.contains(area=MetadataType.FRONTMATTER, key="frontmatter_Key2", value="article") is True
)
assert vm.contains(area=MetadataType.FRONTMATTER, key="frontmatter_Key2", value="none") is False
assert vm.contains(area=MetadataType.FRONTMATTER, key="1$", is_regex=True) is True
assert vm.contains(area=MetadataType.FRONTMATTER, key=r"\d\d", is_regex=True) is False
assert vm.contains(area=MetadataType.INLINE, key="no_key") is False
assert vm.contains(area=MetadataType.INLINE, key="key1") is True
assert vm.contains(area=MetadataType.INLINE, key="key2", value="value3") is True
assert vm.contains(area=MetadataType.INLINE, key="key2", value="none") is False
assert vm.contains(area=MetadataType.INLINE, key="1$", is_regex=True) is True
assert vm.contains(area=MetadataType.INLINE, key=r"\d\d", is_regex=True) is False
assert vm.contains(area=MetadataType.TAGS, value="no_tag") is False
assert vm.contains(area=MetadataType.TAGS, value="tag 1") is True
assert vm.contains(area=MetadataType.TAGS, value=r"\w+ \d$", is_regex=True) is True
assert vm.contains(area=MetadataType.TAGS, value=r"\w+ \d\d$", is_regex=True) is False
with pytest.raises(ValueError):
vm.contains(area=MetadataType.TAGS, key="key1")
def test_vault_metadata_delete() -> None:
"""Test delete method."""
vm = VaultMetadata()
vm.index_metadata(area=MetadataType.FRONTMATTER, metadata=METADATA)
assert vm.dict == {
"frontmatter_Key1": ["author name"],
"frontmatter_Key2": ["article", "note"],
"intext_key": ["intext_key_value"],
"shared_key1": ["shared_key1_value"],
"shared_key2": ["shared_key2_value"],
"tags": ["tag 1", "tag 2", "tag 3"],
"top_key1": ["top_key1_value"],
"top_key2": ["top_key2_value"],
"top_key3": ["top_key3_value"],
}
assert vm.delete("no key") is False
assert vm.delete("tags", "no value") is False
assert vm.delete("tags", "tag 2") is True
assert vm.dict["tags"] == ["tag 1", "tag 3"]
assert vm.delete("tags") is True
assert "tags" not in vm.dict
def test_vault_metadata_rename() -> None:
"""Test rename method."""
vm = VaultMetadata()
vm.index_metadata(area=MetadataType.FRONTMATTER, metadata=METADATA)
assert vm.dict == {
"frontmatter_Key1": ["author name"],
"frontmatter_Key2": ["article", "note"],
"intext_key": ["intext_key_value"],
"shared_key1": ["shared_key1_value"],
"shared_key2": ["shared_key2_value"],
"tags": ["tag 1", "tag 2", "tag 3"],
"top_key1": ["top_key1_value"],
"top_key2": ["top_key2_value"],
"top_key3": ["top_key3_value"],
}
assert vm.rename("no key", "new key") is False
assert vm.rename("tags", "no tag", "new key") is False
assert vm.rename("tags", "tag 2", "new tag") is True
assert vm.dict["tags"] == ["new tag", "tag 1", "tag 3"]
assert vm.rename("tags", "old_tags") is True
assert vm.dict["old_tags"] == ["new tag", "tag 1", "tag 3"]
assert "tags" not in vm.dict