mirror of
https://github.com/natelandau/obsidian-metadata.git
synced 2025-11-15 08:23:47 -05:00
fix: find more instances of inline metadata
This commit is contained in:
@@ -312,7 +312,7 @@ class Frontmatter:
|
|||||||
Returns:
|
Returns:
|
||||||
bool: True if a value was deleted
|
bool: True if a value was deleted
|
||||||
"""
|
"""
|
||||||
new_dict = dict(self.dict)
|
new_dict = copy.deepcopy(self.dict)
|
||||||
|
|
||||||
if value_to_delete is None:
|
if value_to_delete is None:
|
||||||
for _k in list(new_dict):
|
for _k in list(new_dict):
|
||||||
@@ -398,7 +398,7 @@ class InlineMetadata:
|
|||||||
"""Representation of inline metadata in the form of `key:: value`."""
|
"""Representation of inline metadata in the form of `key:: value`."""
|
||||||
|
|
||||||
def __init__(self, file_content: str) -> None:
|
def __init__(self, file_content: str) -> None:
|
||||||
self.dict: dict[str, list[str]] = self.grab_inline_metadata(file_content)
|
self.dict: dict[str, list[str]] = self._grab_inline_metadata(file_content)
|
||||||
self.dict_original: dict[str, list[str]] = copy.deepcopy(self.dict)
|
self.dict_original: dict[str, list[str]] = copy.deepcopy(self.dict)
|
||||||
|
|
||||||
def __repr__(self) -> str: # pragma: no cover
|
def __repr__(self) -> str: # pragma: no cover
|
||||||
@@ -409,6 +409,30 @@ class InlineMetadata:
|
|||||||
"""
|
"""
|
||||||
return f"InlineMetadata(inline_metadata={self.dict})"
|
return f"InlineMetadata(inline_metadata={self.dict})"
|
||||||
|
|
||||||
|
def _grab_inline_metadata(self, file_content: str) -> dict[str, list[str]]:
|
||||||
|
"""Grab inline metadata from a note.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict[str, str]: Inline metadata from the note.
|
||||||
|
"""
|
||||||
|
content = remove_markdown_sections(
|
||||||
|
file_content,
|
||||||
|
strip_codeblocks=True,
|
||||||
|
strip_inlinecode=True,
|
||||||
|
strip_frontmatter=True,
|
||||||
|
)
|
||||||
|
all_results = PATTERNS.find_inline_metadata.findall(content)
|
||||||
|
stripped_null_values = [tuple(filter(None, x)) for x in all_results]
|
||||||
|
|
||||||
|
inline_metadata: dict[str, list[str]] = {}
|
||||||
|
for k, v in stripped_null_values:
|
||||||
|
if k in inline_metadata:
|
||||||
|
inline_metadata[k].append(str(v))
|
||||||
|
else:
|
||||||
|
inline_metadata[k] = [str(v)]
|
||||||
|
|
||||||
|
return clean_dictionary(inline_metadata)
|
||||||
|
|
||||||
def add(self, key: str, value: str | list[str] = None) -> bool: # noqa: PLR0911
|
def add(self, key: str, value: str | list[str] = None) -> bool: # noqa: PLR0911
|
||||||
"""Add a key and value to the inline metadata.
|
"""Add a key and value to the inline metadata.
|
||||||
|
|
||||||
@@ -436,6 +460,7 @@ class InlineMetadata:
|
|||||||
if key in self.dict and value not in self.dict[key]:
|
if key in self.dict and value not in self.dict[key]:
|
||||||
if isinstance(value, list):
|
if isinstance(value, list):
|
||||||
self.dict[key].extend(value)
|
self.dict[key].extend(value)
|
||||||
|
self.dict[key] = list(sorted(set(self.dict[key])))
|
||||||
return True
|
return True
|
||||||
|
|
||||||
self.dict[key].append(value)
|
self.dict[key].append(value)
|
||||||
@@ -484,30 +509,6 @@ class InlineMetadata:
|
|||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def grab_inline_metadata(self, file_content: str) -> dict[str, list[str]]:
|
|
||||||
"""Grab inline metadata from a note.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
dict[str, str]: Inline metadata from the note.
|
|
||||||
"""
|
|
||||||
content = remove_markdown_sections(
|
|
||||||
file_content,
|
|
||||||
strip_codeblocks=True,
|
|
||||||
strip_inlinecode=True,
|
|
||||||
strip_frontmatter=True,
|
|
||||||
)
|
|
||||||
all_results = PATTERNS.find_inline_metadata.findall(content)
|
|
||||||
stripped_null_values = [tuple(filter(None, x)) for x in all_results]
|
|
||||||
|
|
||||||
inline_metadata: dict[str, list[str]] = {}
|
|
||||||
for k, v in stripped_null_values:
|
|
||||||
if k in inline_metadata:
|
|
||||||
inline_metadata[k].append(str(v))
|
|
||||||
else:
|
|
||||||
inline_metadata[k] = [str(v)]
|
|
||||||
|
|
||||||
return clean_dictionary(inline_metadata)
|
|
||||||
|
|
||||||
def has_changes(self) -> bool:
|
def has_changes(self) -> bool:
|
||||||
"""Check if the metadata has changes.
|
"""Check if the metadata has changes.
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ class Patterns:
|
|||||||
([-_\w\d\/\*\u263a-\U0001f999]+?)::[ ]? # Find key
|
([-_\w\d\/\*\u263a-\U0001f999]+?)::[ ]? # Find key
|
||||||
(.*?)\] # Find value until closing bracket
|
(.*?)\] # Find value until closing bracket
|
||||||
| # Else look for key values at start of line
|
| # Else look for key values at start of line
|
||||||
(?:^|[^ \w\d]+| \[) # Any non-word or non-digit character
|
(?:^|[^ \w\d]+|^ *>?[-\d\|]?\.? ) # Any non-word or non-digit character
|
||||||
([-_\w\d\/\*\u263a-\U0001f9995]+?)::(?!\n)(?:[ ](?!\n))? # Capture the key if not a new line
|
([-_\w\d\/\*\u263a-\U0001f9995]+?)::(?!\n)(?:[ ](?!\n))? # Capture the key if not a new line
|
||||||
(.*?)$ # Capture the value
|
(.*?)$ # Capture the value
|
||||||
""",
|
""",
|
||||||
|
|||||||
530
tests/metadata_frontmatter_test.py
Normal file
530
tests/metadata_frontmatter_test.py
Normal file
@@ -0,0 +1,530 @@
|
|||||||
|
# type: ignore
|
||||||
|
"""Test the Frontmatter object from metadata.py."""
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from obsidian_metadata.models.metadata import Frontmatter
|
||||||
|
|
||||||
|
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_frontmatter_create_1() -> None:
|
||||||
|
"""Test frontmatter creation.
|
||||||
|
|
||||||
|
GIVEN valid frontmatter content
|
||||||
|
WHEN a Frontmatter object is created
|
||||||
|
THEN parse the YAML frontmatter and add it to the object
|
||||||
|
"""
|
||||||
|
frontmatter = Frontmatter(INLINE_CONTENT)
|
||||||
|
assert frontmatter.dict == {}
|
||||||
|
|
||||||
|
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
||||||
|
assert frontmatter.dict == {
|
||||||
|
"frontmatter_Key1": ["frontmatter_Key1_value"],
|
||||||
|
"frontmatter_Key2": ["article", "note"],
|
||||||
|
"shared_key1": ["shared_key1_value"],
|
||||||
|
"tags": ["tag_1", "tag_2", "📅/tag_3"],
|
||||||
|
}
|
||||||
|
assert frontmatter.dict_original == {
|
||||||
|
"frontmatter_Key1": ["frontmatter_Key1_value"],
|
||||||
|
"frontmatter_Key2": ["article", "note"],
|
||||||
|
"shared_key1": ["shared_key1_value"],
|
||||||
|
"tags": ["tag_1", "tag_2", "📅/tag_3"],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def test_frontmatter_create_2() -> None:
|
||||||
|
"""Test frontmatter creation error.
|
||||||
|
|
||||||
|
GIVEN invalid frontmatter content
|
||||||
|
WHEN a Frontmatter object is created
|
||||||
|
THEN raise ValueError
|
||||||
|
"""
|
||||||
|
fn = """---
|
||||||
|
tags: tag
|
||||||
|
invalid = = "content"
|
||||||
|
---
|
||||||
|
"""
|
||||||
|
with pytest.raises(AttributeError):
|
||||||
|
Frontmatter(fn)
|
||||||
|
|
||||||
|
|
||||||
|
def test_frontmatter_create_3():
|
||||||
|
"""Test frontmatter creation error.
|
||||||
|
|
||||||
|
GIVEN empty frontmatter content
|
||||||
|
WHEN a Frontmatter object is created
|
||||||
|
THEN set the dict to an empty dict
|
||||||
|
"""
|
||||||
|
content = "---\n\n---"
|
||||||
|
frontmatter = Frontmatter(content)
|
||||||
|
assert frontmatter.dict == {}
|
||||||
|
|
||||||
|
|
||||||
|
def test_frontmatter_create_4():
|
||||||
|
"""Test frontmatter creation error.
|
||||||
|
|
||||||
|
GIVEN empty frontmatter content with a yaml marker
|
||||||
|
WHEN a Frontmatter object is created
|
||||||
|
THEN set the dict to an empty dict
|
||||||
|
"""
|
||||||
|
content = "---\n-\n---"
|
||||||
|
frontmatter = Frontmatter(content)
|
||||||
|
assert frontmatter.dict == {}
|
||||||
|
|
||||||
|
|
||||||
|
def test_frontmatter_add_1():
|
||||||
|
"""Test frontmatter add() method.
|
||||||
|
|
||||||
|
GIVEN a Frontmatter object
|
||||||
|
WHEN the add() method is called with an existing key
|
||||||
|
THEN return False
|
||||||
|
"""
|
||||||
|
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
||||||
|
|
||||||
|
assert frontmatter.add("frontmatter_Key1") is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_frontmatter_add_2():
|
||||||
|
"""Test frontmatter add() method.
|
||||||
|
|
||||||
|
GIVEN a Frontmatter object
|
||||||
|
WHEN the add() method is called with an existing key and existing value
|
||||||
|
THEN return False
|
||||||
|
"""
|
||||||
|
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
||||||
|
assert frontmatter.add("frontmatter_Key1", "frontmatter_Key1_value") is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_frontmatter_add_3():
|
||||||
|
"""Test frontmatter add() method.
|
||||||
|
|
||||||
|
GIVEN a Frontmatter object
|
||||||
|
WHEN the add() method is called with a new key
|
||||||
|
THEN return True and add the key to the dict
|
||||||
|
"""
|
||||||
|
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
||||||
|
assert frontmatter.add("added_key") is True
|
||||||
|
assert "added_key" in frontmatter.dict
|
||||||
|
|
||||||
|
|
||||||
|
def test_frontmatter_add_4():
|
||||||
|
"""Test frontmatter add() method.
|
||||||
|
|
||||||
|
GIVEN a Frontmatter object
|
||||||
|
WHEN the add() method is called with a new key and a new value
|
||||||
|
THEN return True and add the key and the value to the dict
|
||||||
|
"""
|
||||||
|
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
||||||
|
assert frontmatter.add("added_key", "added_value") is True
|
||||||
|
assert frontmatter.dict["added_key"] == ["added_value"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_frontmatter_add_5():
|
||||||
|
"""Test frontmatter add() method.
|
||||||
|
|
||||||
|
GIVEN a Frontmatter object
|
||||||
|
WHEN the add() method is called with an existing key and a new value
|
||||||
|
THEN return True and add the value to the dict
|
||||||
|
"""
|
||||||
|
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
||||||
|
assert frontmatter.add("frontmatter_Key1", "new_value") is True
|
||||||
|
assert frontmatter.dict["frontmatter_Key1"] == ["frontmatter_Key1_value", "new_value"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_frontmatter_add_6():
|
||||||
|
"""Test frontmatter add() method.
|
||||||
|
|
||||||
|
GIVEN a Frontmatter object
|
||||||
|
WHEN the add() method is called with an existing key and a list of new values
|
||||||
|
THEN return True and add the values to the dict
|
||||||
|
"""
|
||||||
|
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
||||||
|
assert frontmatter.add("frontmatter_Key1", ["new_value", "new_value2"]) is True
|
||||||
|
assert frontmatter.dict["frontmatter_Key1"] == [
|
||||||
|
"frontmatter_Key1_value",
|
||||||
|
"new_value",
|
||||||
|
"new_value2",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def test_frontmatter_add_7():
|
||||||
|
"""Test frontmatter add() method.
|
||||||
|
|
||||||
|
GIVEN a Frontmatter object
|
||||||
|
WHEN the add() method is called with an existing key and a list of values including an existing value
|
||||||
|
THEN return True and add the new values to the dict
|
||||||
|
"""
|
||||||
|
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
||||||
|
assert (
|
||||||
|
frontmatter.add("frontmatter_Key1", ["frontmatter_Key1_value", "new_value", "new_value2"])
|
||||||
|
is True
|
||||||
|
)
|
||||||
|
assert frontmatter.dict["frontmatter_Key1"] == [
|
||||||
|
"frontmatter_Key1_value",
|
||||||
|
"new_value",
|
||||||
|
"new_value2",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def test_frontmatter_contains_1():
|
||||||
|
"""Test frontmatter contains() method.
|
||||||
|
|
||||||
|
GIVEN a Frontmatter object
|
||||||
|
WHEN the contains() method is called with a key
|
||||||
|
THEN return True if the key is found
|
||||||
|
"""
|
||||||
|
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
||||||
|
assert frontmatter.contains("frontmatter_Key1") is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_frontmatter_contains_2():
|
||||||
|
"""Test frontmatter contains() method.
|
||||||
|
|
||||||
|
GIVEN a Frontmatter object
|
||||||
|
WHEN the contains() method is called with a key
|
||||||
|
THEN return False if the key is not found
|
||||||
|
"""
|
||||||
|
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
||||||
|
assert frontmatter.contains("no_key") is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_frontmatter_contains_3():
|
||||||
|
"""Test frontmatter contains() method.
|
||||||
|
|
||||||
|
GIVEN a Frontmatter object
|
||||||
|
WHEN the contains() method is called with a key and a value
|
||||||
|
THEN return True if the key and value is found
|
||||||
|
"""
|
||||||
|
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
||||||
|
assert frontmatter.contains("frontmatter_Key2", "article") is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_frontmatter_contains_4():
|
||||||
|
"""Test frontmatter contains() method.
|
||||||
|
|
||||||
|
GIVEN a Frontmatter object
|
||||||
|
WHEN the contains() method is called with a key and a value
|
||||||
|
THEN return False if the key and value is not found
|
||||||
|
"""
|
||||||
|
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
||||||
|
assert frontmatter.contains("frontmatter_Key2", "no value") is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_frontmatter_contains_5():
|
||||||
|
"""Test frontmatter contains() method.
|
||||||
|
|
||||||
|
GIVEN a Frontmatter object
|
||||||
|
WHEN the contains() method is called with a key regex
|
||||||
|
THEN return True if a key matches the regex
|
||||||
|
"""
|
||||||
|
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
||||||
|
assert frontmatter.contains(r"\d$", is_regex=True) is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_frontmatter_contains_6():
|
||||||
|
"""Test frontmatter contains() method.
|
||||||
|
|
||||||
|
GIVEN a Frontmatter object
|
||||||
|
WHEN the contains() method is called with a key regex
|
||||||
|
THEN return False if no key matches the regex
|
||||||
|
"""
|
||||||
|
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
||||||
|
assert frontmatter.contains(r"^\d", is_regex=True) is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_frontmatter_contains_7():
|
||||||
|
"""Test frontmatter contains() method.
|
||||||
|
|
||||||
|
GIVEN a Frontmatter object
|
||||||
|
WHEN the contains() method is called with a key and value regex
|
||||||
|
THEN return True if a value matches the regex
|
||||||
|
"""
|
||||||
|
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
||||||
|
assert frontmatter.contains("key", r"\w\d_", is_regex=True) is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_frontmatter_contains_8():
|
||||||
|
"""Test frontmatter contains() method.
|
||||||
|
|
||||||
|
GIVEN a Frontmatter object
|
||||||
|
WHEN the contains() method is called with a key and value regex
|
||||||
|
THEN return False if a value does not match the regex
|
||||||
|
"""
|
||||||
|
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
||||||
|
assert frontmatter.contains("key", r"_\d", is_regex=True) is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_frontmatter_delete_1():
|
||||||
|
"""Test frontmatter delete() method.
|
||||||
|
|
||||||
|
GIVEN a Frontmatter object
|
||||||
|
WHEN the delete() method is called with a key that does not exist
|
||||||
|
THEN return False
|
||||||
|
"""
|
||||||
|
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
||||||
|
assert frontmatter.delete("no key") is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_frontmatter_delete_2():
|
||||||
|
"""Test frontmatter delete() method.
|
||||||
|
|
||||||
|
GIVEN a Frontmatter object
|
||||||
|
WHEN the delete() method is called with an existing key and a value that does not exist
|
||||||
|
THEN return False
|
||||||
|
"""
|
||||||
|
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
||||||
|
assert frontmatter.delete("tags", "no value") is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_frontmatter_delete_3():
|
||||||
|
"""Test frontmatter delete() method.
|
||||||
|
|
||||||
|
GIVEN a Frontmatter object
|
||||||
|
WHEN the delete() method is called with a regex that does not match any keys
|
||||||
|
THEN return False
|
||||||
|
"""
|
||||||
|
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
||||||
|
assert frontmatter.delete(r"\d{3}") is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_frontmatter_delete_4():
|
||||||
|
"""Test frontmatter delete() method.
|
||||||
|
|
||||||
|
GIVEN a Frontmatter object
|
||||||
|
WHEN the delete() method is called with an existing key and a regex that does not match any values
|
||||||
|
THEN return False
|
||||||
|
"""
|
||||||
|
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
||||||
|
assert frontmatter.delete("tags", r"\d{5}") is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_frontmatter_delete_5():
|
||||||
|
"""Test frontmatter delete() method.
|
||||||
|
|
||||||
|
GIVEN a Frontmatter object
|
||||||
|
WHEN the delete() method is called with an existing key and an existing value
|
||||||
|
THEN return True and delete the value from the dict
|
||||||
|
"""
|
||||||
|
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
||||||
|
assert frontmatter.delete("tags", "tag_2") is True
|
||||||
|
assert "tag_2" not in frontmatter.dict["tags"]
|
||||||
|
assert "tags" in frontmatter.dict
|
||||||
|
|
||||||
|
|
||||||
|
def test_frontmatter_delete_6():
|
||||||
|
"""Test frontmatter delete() method.
|
||||||
|
|
||||||
|
GIVEN a Frontmatter object
|
||||||
|
WHEN the delete() method is called with an existing key
|
||||||
|
THEN return True and delete the key from the dict
|
||||||
|
"""
|
||||||
|
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
||||||
|
assert frontmatter.delete("tags") is True
|
||||||
|
assert "tags" not in frontmatter.dict
|
||||||
|
|
||||||
|
|
||||||
|
def test_frontmatter_delete_7():
|
||||||
|
"""Test frontmatter delete() method.
|
||||||
|
|
||||||
|
GIVEN a Frontmatter object
|
||||||
|
WHEN the delete() method is called with a regex that matches a key
|
||||||
|
THEN return True and delete the matching keys from the dict
|
||||||
|
"""
|
||||||
|
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
||||||
|
assert frontmatter.delete(r"front\w+") is True
|
||||||
|
assert "frontmatter_Key1" not in frontmatter.dict
|
||||||
|
assert "frontmatter_Key2" not in frontmatter.dict
|
||||||
|
|
||||||
|
|
||||||
|
def test_frontmatter_delete_8():
|
||||||
|
"""Test frontmatter delete() method.
|
||||||
|
|
||||||
|
GIVEN a Frontmatter object
|
||||||
|
WHEN the delete() method is called with an existing key and a regex that matches values
|
||||||
|
THEN return True and delete the matching values
|
||||||
|
"""
|
||||||
|
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
||||||
|
assert frontmatter.delete("tags", r"\w+_[23]") is True
|
||||||
|
assert "tag_2" not in frontmatter.dict["tags"]
|
||||||
|
assert "📅/tag_3" not in frontmatter.dict["tags"]
|
||||||
|
assert "tag_1" in frontmatter.dict["tags"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_frontmatter_delete_all():
|
||||||
|
"""Test Frontmatter delete_all method.
|
||||||
|
|
||||||
|
GIVEN Frontmatter with multiple keys
|
||||||
|
WHEN delete_all is called
|
||||||
|
THEN all keys and values are deleted
|
||||||
|
"""
|
||||||
|
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
||||||
|
frontmatter.delete_all()
|
||||||
|
assert frontmatter.dict == {}
|
||||||
|
|
||||||
|
|
||||||
|
def test_frontmatter_has_changes_1():
|
||||||
|
"""Test frontmatter has_changes() method.
|
||||||
|
|
||||||
|
GIVEN a Frontmatter object
|
||||||
|
WHEN no changes have been made to the object
|
||||||
|
THEN return False
|
||||||
|
"""
|
||||||
|
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
||||||
|
assert frontmatter.has_changes() is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_frontmatter_has_changes_2():
|
||||||
|
"""Test frontmatter has_changes() method.
|
||||||
|
|
||||||
|
GIVEN a Frontmatter object
|
||||||
|
WHEN changes have been made to the object
|
||||||
|
THEN return True
|
||||||
|
"""
|
||||||
|
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
||||||
|
frontmatter.dict["new key"] = ["new value"]
|
||||||
|
assert frontmatter.has_changes() is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_frontmatter_rename_1():
|
||||||
|
"""Test frontmatter rename() method.
|
||||||
|
|
||||||
|
GIVEN a Frontmatter object
|
||||||
|
WHEN the rename() method is called with a key
|
||||||
|
THEN return False if the key is not found
|
||||||
|
"""
|
||||||
|
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
||||||
|
assert frontmatter.rename("no key", "new key") is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_frontmatter_rename_2():
|
||||||
|
"""Test frontmatter rename() method.
|
||||||
|
|
||||||
|
GIVEN a Frontmatter object
|
||||||
|
WHEN the rename() method is called with an existing key and non-existing value
|
||||||
|
THEN return False
|
||||||
|
"""
|
||||||
|
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
||||||
|
assert frontmatter.rename("tags", "no tag", "new key") is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_frontmatter_rename_3():
|
||||||
|
"""Test frontmatter rename() method.
|
||||||
|
|
||||||
|
GIVEN a Frontmatter object
|
||||||
|
WHEN the rename() method is called with an existing key
|
||||||
|
THEN return True and rename the key
|
||||||
|
"""
|
||||||
|
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
||||||
|
assert frontmatter.rename("frontmatter_Key1", "new key") is True
|
||||||
|
assert "frontmatter_Key1" not in frontmatter.dict
|
||||||
|
assert frontmatter.dict["new key"] == ["frontmatter_Key1_value"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_frontmatter_rename_4():
|
||||||
|
"""Test frontmatter rename() method.
|
||||||
|
|
||||||
|
GIVEN a Frontmatter object
|
||||||
|
WHEN the rename() method is called with an existing key and value
|
||||||
|
THEN return True and rename the value
|
||||||
|
"""
|
||||||
|
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
||||||
|
assert frontmatter.rename("tags", "tag_2", "new tag") is True
|
||||||
|
assert "tag_2" not in frontmatter.dict["tags"]
|
||||||
|
assert "new tag" in frontmatter.dict["tags"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_frontmatter_rename_5():
|
||||||
|
"""Test frontmatter rename() method.
|
||||||
|
|
||||||
|
GIVEN a Frontmatter object
|
||||||
|
WHEN the rename() method is called with an existing key and value and the new value already exists
|
||||||
|
THEN return True and remove the old value leaving one instance of the new value
|
||||||
|
"""
|
||||||
|
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
||||||
|
assert frontmatter.rename("tags", "tag_1", "tag_2") is True
|
||||||
|
assert "tag_1" not in frontmatter.dict["tags"]
|
||||||
|
assert frontmatter.dict["tags"] == ["tag_2", "📅/tag_3"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_frontmatter_to_yaml_1():
|
||||||
|
"""Test Frontmatter to_yaml method.
|
||||||
|
|
||||||
|
GIVEN a dictionary
|
||||||
|
WHEN the to_yaml method is called
|
||||||
|
THEN return a string with the yaml representation of the dictionary
|
||||||
|
"""
|
||||||
|
new_frontmatter: str = """\
|
||||||
|
tags:
|
||||||
|
- tag_1
|
||||||
|
- tag_2
|
||||||
|
- 📅/tag_3
|
||||||
|
frontmatter_Key1: frontmatter_Key1_value
|
||||||
|
frontmatter_Key2:
|
||||||
|
- article
|
||||||
|
- note
|
||||||
|
shared_key1: shared_key1_value
|
||||||
|
"""
|
||||||
|
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
||||||
|
assert frontmatter.to_yaml() == new_frontmatter
|
||||||
|
|
||||||
|
|
||||||
|
def test_frontmatter_to_yaml_2():
|
||||||
|
"""Test Frontmatter to_yaml method.
|
||||||
|
|
||||||
|
GIVEN a dictionary
|
||||||
|
WHEN the to_yaml method is called with sort_keys=True
|
||||||
|
THEN return a string with the sorted yaml representation of the dictionary
|
||||||
|
"""
|
||||||
|
new_frontmatter_sorted: str = """\
|
||||||
|
frontmatter_Key1: frontmatter_Key1_value
|
||||||
|
frontmatter_Key2:
|
||||||
|
- article
|
||||||
|
- note
|
||||||
|
shared_key1: shared_key1_value
|
||||||
|
tags:
|
||||||
|
- tag_1
|
||||||
|
- tag_2
|
||||||
|
- 📅/tag_3
|
||||||
|
"""
|
||||||
|
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
||||||
|
assert frontmatter.to_yaml(sort_keys=True) == new_frontmatter_sorted
|
||||||
426
tests/metadata_inline_test.py
Normal file
426
tests/metadata_inline_test.py
Normal file
@@ -0,0 +1,426 @@
|
|||||||
|
# type: ignore
|
||||||
|
"""Test inline metadata from metadata.py."""
|
||||||
|
|
||||||
|
from obsidian_metadata.models.metadata import InlineMetadata
|
||||||
|
|
||||||
|
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 = """\
|
||||||
|
key1:: value1
|
||||||
|
key1:: value2
|
||||||
|
key1:: value3
|
||||||
|
key2:: value1
|
||||||
|
Paragraph of text with an [inline_key:: value1] and [inline_key:: value2] and [inline_key:: value3] which should do it.
|
||||||
|
> blockquote_key:: value1
|
||||||
|
> blockquote_key:: value2
|
||||||
|
|
||||||
|
- list_key:: value1
|
||||||
|
- list_key:: value2
|
||||||
|
|
||||||
|
1. list_key:: value1
|
||||||
|
2. list_key:: value2
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def test__grab_inline_metadata_1():
|
||||||
|
"""Test grab inline metadata.
|
||||||
|
|
||||||
|
GIVEN content that has no inline metadata
|
||||||
|
WHEN grab_inline_metadata is called
|
||||||
|
THEN an empty dict is returned
|
||||||
|
|
||||||
|
"""
|
||||||
|
content = """
|
||||||
|
---
|
||||||
|
frontmatter_key1: frontmatter_key1_value
|
||||||
|
---
|
||||||
|
not_a_key: not_a_value
|
||||||
|
```
|
||||||
|
key:: in_codeblock
|
||||||
|
```
|
||||||
|
"""
|
||||||
|
inline = InlineMetadata(content)
|
||||||
|
assert inline.dict == {}
|
||||||
|
|
||||||
|
|
||||||
|
def test__grab_inline_metadata_2():
|
||||||
|
"""Test grab inline metadata.
|
||||||
|
|
||||||
|
GIVEN content that has inline metadata
|
||||||
|
WHEN grab_inline_metadata is called
|
||||||
|
THEN the inline metadata is parsed and returned as a dict
|
||||||
|
|
||||||
|
"""
|
||||||
|
inline = InlineMetadata(INLINE_CONTENT)
|
||||||
|
assert inline.dict == {
|
||||||
|
"blockquote_key": ["value1", "value2"],
|
||||||
|
"inline_key": ["value1", "value2", "value3"],
|
||||||
|
"key1": ["value1", "value2", "value3"],
|
||||||
|
"key2": ["value1"],
|
||||||
|
"list_key": ["value1", "value2", "value1", "value2"],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def test_inline_metadata_add_1():
|
||||||
|
"""Test InlineMetadata add() method.
|
||||||
|
|
||||||
|
GIVEN a InlineMetadata object
|
||||||
|
WHEN the add() method is called with an existing key
|
||||||
|
THEN return False
|
||||||
|
"""
|
||||||
|
inline = InlineMetadata(INLINE_CONTENT)
|
||||||
|
assert inline.add("key1") is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_inline_metadata_add_2():
|
||||||
|
"""Test InlineMetadata add() method.
|
||||||
|
|
||||||
|
GIVEN a InlineMetadata object
|
||||||
|
WHEN the add() method is called with an existing key and existing value
|
||||||
|
THEN return False
|
||||||
|
"""
|
||||||
|
inline = InlineMetadata(INLINE_CONTENT)
|
||||||
|
assert inline.add("key1", "value1") is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_inline_metadata_add_3():
|
||||||
|
"""Test InlineMetadata add() method.
|
||||||
|
|
||||||
|
GIVEN a InlineMetadata object
|
||||||
|
WHEN the add() method is called with a new key
|
||||||
|
THEN return True and add the key to the dict
|
||||||
|
"""
|
||||||
|
inline = InlineMetadata(INLINE_CONTENT)
|
||||||
|
assert inline.add("added_key") is True
|
||||||
|
assert "added_key" in inline.dict
|
||||||
|
|
||||||
|
|
||||||
|
def test_inline_metadata_add_4():
|
||||||
|
"""Test InlineMetadata add() method.
|
||||||
|
|
||||||
|
GIVEN a InlineMetadata object
|
||||||
|
WHEN the add() method is called with a new key and a new value
|
||||||
|
THEN return True and add the key and the value to the dict
|
||||||
|
"""
|
||||||
|
inline = InlineMetadata(INLINE_CONTENT)
|
||||||
|
assert inline.add("added_key", "added_value") is True
|
||||||
|
assert inline.dict["added_key"] == ["added_value"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_inline_metadata_add_5():
|
||||||
|
"""Test InlineMetadata add() method.
|
||||||
|
|
||||||
|
GIVEN a InlineMetadata object
|
||||||
|
WHEN the add() method is called with an existing key and a new value
|
||||||
|
THEN return True and add the value to the dict
|
||||||
|
"""
|
||||||
|
inline = InlineMetadata(INLINE_CONTENT)
|
||||||
|
assert inline.add("key1", "new_value") is True
|
||||||
|
assert inline.dict["key1"] == ["value1", "value2", "value3", "new_value"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_inline_metadata_add_6():
|
||||||
|
"""Test InlineMetadata add() method.
|
||||||
|
|
||||||
|
GIVEN a InlineMetadata object
|
||||||
|
WHEN the add() method is called with an existing key and a list of new values
|
||||||
|
THEN return True and add the values to the dict
|
||||||
|
"""
|
||||||
|
inline = InlineMetadata(INLINE_CONTENT)
|
||||||
|
assert inline.add("key2", ["new_value", "new_value2"]) is True
|
||||||
|
assert inline.dict["key2"] == ["new_value", "new_value2", "value1"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_inline_metadata_add_7():
|
||||||
|
"""Test InlineMetadata add() method.
|
||||||
|
|
||||||
|
GIVEN a InlineMetadata object
|
||||||
|
WHEN the add() method is called with an existing key and a list of values including an existing value
|
||||||
|
THEN return True and add the new values to the dict
|
||||||
|
"""
|
||||||
|
inline = InlineMetadata(INLINE_CONTENT)
|
||||||
|
assert inline.add("key1", ["value1", "new_value", "new_value2"]) is True
|
||||||
|
assert inline.dict["key1"] == ["new_value", "new_value2", "value1", "value2", "value3"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_inline_metadata_contains_1():
|
||||||
|
"""Test InlineMetadata contains() method.
|
||||||
|
|
||||||
|
GIVEN a InlineMetadata object
|
||||||
|
WHEN the contains() method is called with a key
|
||||||
|
THEN return True if the key is found
|
||||||
|
"""
|
||||||
|
inline = InlineMetadata(INLINE_CONTENT)
|
||||||
|
assert inline.contains("key1") is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_inline_metadata_contains_2():
|
||||||
|
"""Test InlineMetadata contains() method.
|
||||||
|
|
||||||
|
GIVEN a InlineMetadata object
|
||||||
|
WHEN the contains() method is called with a key
|
||||||
|
THEN return False if the key is not found
|
||||||
|
"""
|
||||||
|
inline = InlineMetadata(INLINE_CONTENT)
|
||||||
|
assert inline.contains("no_key") is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_inline_metadata_contains_3():
|
||||||
|
"""Test InlineMetadata contains() method.
|
||||||
|
|
||||||
|
GIVEN a InlineMetadata object
|
||||||
|
WHEN the contains() method is called with a key and a value
|
||||||
|
THEN return True if the key and value is found
|
||||||
|
"""
|
||||||
|
inline = InlineMetadata(INLINE_CONTENT)
|
||||||
|
assert inline.contains("key1", "value1") is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_inline_metadata_contains_4():
|
||||||
|
"""Test InlineMetadata contains() method.
|
||||||
|
|
||||||
|
GIVEN a InlineMetadata object
|
||||||
|
WHEN the contains() method is called with a key and a value
|
||||||
|
THEN return False if the key and value is not found
|
||||||
|
"""
|
||||||
|
inline = InlineMetadata(INLINE_CONTENT)
|
||||||
|
assert inline.contains("key1", "no value") is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_inline_metadata_contains_5():
|
||||||
|
"""Test InlineMetadata contains() method.
|
||||||
|
|
||||||
|
GIVEN a InlineMetadata object
|
||||||
|
WHEN the contains() method is called with a key regex
|
||||||
|
THEN return True if a key matches the regex
|
||||||
|
"""
|
||||||
|
inline = InlineMetadata(INLINE_CONTENT)
|
||||||
|
assert inline.contains(r"\d$", is_regex=True) is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_inline_metadata_contains_6():
|
||||||
|
"""Test InlineMetadata contains() method.
|
||||||
|
|
||||||
|
GIVEN a InlineMetadata object
|
||||||
|
WHEN the contains() method is called with a key regex
|
||||||
|
THEN return False if no key matches the regex
|
||||||
|
"""
|
||||||
|
inline = InlineMetadata(INLINE_CONTENT)
|
||||||
|
assert inline.contains(r"^\d", is_regex=True) is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_inline_metadata_contains_7():
|
||||||
|
"""Test InlineMetadata contains() method.
|
||||||
|
|
||||||
|
GIVEN a InlineMetadata object
|
||||||
|
WHEN the contains() method is called with a key and value regex
|
||||||
|
THEN return True if a value matches the regex
|
||||||
|
"""
|
||||||
|
inline = InlineMetadata(INLINE_CONTENT)
|
||||||
|
assert inline.contains(r"key\d", r"\w\d", is_regex=True) is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_inline_metadata_contains_8():
|
||||||
|
"""Test InlineMetadata contains() method.
|
||||||
|
|
||||||
|
GIVEN a InlineMetadata object
|
||||||
|
WHEN the contains() method is called with a key and value regex
|
||||||
|
THEN return False if a value does not match the regex
|
||||||
|
"""
|
||||||
|
inline = InlineMetadata(INLINE_CONTENT)
|
||||||
|
assert inline.contains("key1", r"_\d", is_regex=True) is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_inline_metadata_delete_1():
|
||||||
|
"""Test InlineMetadata delete() method.
|
||||||
|
|
||||||
|
GIVEN a InlineMetadata object
|
||||||
|
WHEN the delete() method is called with a key that does not exist
|
||||||
|
THEN return False
|
||||||
|
"""
|
||||||
|
inline = InlineMetadata(INLINE_CONTENT)
|
||||||
|
assert inline.delete("no key") is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_inline_metadata_delete_2():
|
||||||
|
"""Test InlineMetadata delete() method.
|
||||||
|
|
||||||
|
GIVEN a InlineMetadata object
|
||||||
|
WHEN the delete() method is called with an existing key and a value that does not exist
|
||||||
|
THEN return False
|
||||||
|
"""
|
||||||
|
inline = InlineMetadata(INLINE_CONTENT)
|
||||||
|
assert inline.delete("key1", "no value") is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_inline_metadata_delete_3():
|
||||||
|
"""Test InlineMetadata delete() method.
|
||||||
|
|
||||||
|
GIVEN a InlineMetadata object
|
||||||
|
WHEN the delete() method is called with a regex that does not match any keys
|
||||||
|
THEN return False
|
||||||
|
"""
|
||||||
|
inline = InlineMetadata(INLINE_CONTENT)
|
||||||
|
assert inline.delete(r"\d{3}") is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_inline_metadata_delete_4():
|
||||||
|
"""Test InlineMetadata delete() method.
|
||||||
|
|
||||||
|
GIVEN a InlineMetadata object
|
||||||
|
WHEN the delete() method is called with an existing key and a regex that does not match any values
|
||||||
|
THEN return False
|
||||||
|
"""
|
||||||
|
inline = InlineMetadata(INLINE_CONTENT)
|
||||||
|
assert inline.delete("key1", r"\d{5}") is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_inline_metadata_delete_5():
|
||||||
|
"""Test InlineMetadata delete() method.
|
||||||
|
|
||||||
|
GIVEN a InlineMetadata object
|
||||||
|
WHEN the delete() method is called with an existing key and an existing value
|
||||||
|
THEN return True and delete the value from the dict
|
||||||
|
"""
|
||||||
|
inline = InlineMetadata(INLINE_CONTENT)
|
||||||
|
assert inline.delete("key1", "value1") is True
|
||||||
|
assert "value1" not in inline.dict["key1"]
|
||||||
|
assert "key1" in inline.dict
|
||||||
|
|
||||||
|
|
||||||
|
def test_inline_metadata_delete_6():
|
||||||
|
"""Test InlineMetadata delete() method.
|
||||||
|
|
||||||
|
GIVEN a InlineMetadata object
|
||||||
|
WHEN the delete() method is called with an existing key
|
||||||
|
THEN return True and delete the key from the dict
|
||||||
|
"""
|
||||||
|
inline = InlineMetadata(INLINE_CONTENT)
|
||||||
|
assert inline.delete("key1") is True
|
||||||
|
assert "key1" not in inline.dict
|
||||||
|
|
||||||
|
|
||||||
|
def test_inline_metadata_delete_7():
|
||||||
|
"""Test InlineMetadata delete() method.
|
||||||
|
|
||||||
|
GIVEN a InlineMetadata object
|
||||||
|
WHEN the delete() method is called with a regex that matches a key
|
||||||
|
THEN return True and delete the matching keys from the dict
|
||||||
|
"""
|
||||||
|
inline = InlineMetadata(INLINE_CONTENT)
|
||||||
|
assert inline.delete(r"key\w+") is True
|
||||||
|
assert "key1" not in inline.dict
|
||||||
|
assert "key2" not in inline.dict
|
||||||
|
|
||||||
|
|
||||||
|
def test_inline_metadata_delete_8():
|
||||||
|
"""Test InlineMetadata delete() method.
|
||||||
|
|
||||||
|
GIVEN a InlineMetadata object
|
||||||
|
WHEN the delete() method is called with an existing key and a regex that matches values
|
||||||
|
THEN return True and delete the matching values
|
||||||
|
"""
|
||||||
|
inline = InlineMetadata(INLINE_CONTENT)
|
||||||
|
assert inline.delete("key1", r"\w+\d") is True
|
||||||
|
assert "value1" not in inline.dict["key1"]
|
||||||
|
assert "value2" not in inline.dict["key1"]
|
||||||
|
assert "value3" not in inline.dict["key1"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_inline_metadata_has_changes_1():
|
||||||
|
"""Test InlineMetadata has_changes() method.
|
||||||
|
|
||||||
|
GIVEN a InlineMetadata object
|
||||||
|
WHEN no changes have been made to the object
|
||||||
|
THEN return False
|
||||||
|
"""
|
||||||
|
inline = InlineMetadata(INLINE_CONTENT)
|
||||||
|
assert inline.has_changes() is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_inline_metadata_has_changes_2():
|
||||||
|
"""Test InlineMetadata has_changes() method.
|
||||||
|
|
||||||
|
GIVEN a InlineMetadata object
|
||||||
|
WHEN changes have been made to the object
|
||||||
|
THEN return True
|
||||||
|
"""
|
||||||
|
inline = InlineMetadata(INLINE_CONTENT)
|
||||||
|
inline.dict["new key"] = ["new value"]
|
||||||
|
assert inline.has_changes() is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_inline_metadata_rename_1():
|
||||||
|
"""Test InlineMetadata rename() method.
|
||||||
|
|
||||||
|
GIVEN a InlineMetadata object
|
||||||
|
WHEN the rename() method is called with a key
|
||||||
|
THEN return False if the key is not found
|
||||||
|
"""
|
||||||
|
inline = InlineMetadata(INLINE_CONTENT)
|
||||||
|
assert inline.rename("no key", "new key") is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_inline_metadata_rename_2():
|
||||||
|
"""Test InlineMetadata rename() method.
|
||||||
|
|
||||||
|
GIVEN a InlineMetadata object
|
||||||
|
WHEN the rename() method is called with an existing key and non-existing value
|
||||||
|
THEN return False
|
||||||
|
"""
|
||||||
|
inline = InlineMetadata(INLINE_CONTENT)
|
||||||
|
assert inline.rename("key1", "no value", "new value") is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_inline_metadata_rename_3():
|
||||||
|
"""Test InlineMetadata rename() method.
|
||||||
|
|
||||||
|
GIVEN a InlineMetadata object
|
||||||
|
WHEN the rename() method is called with an existing key
|
||||||
|
THEN return True and rename the key
|
||||||
|
"""
|
||||||
|
inline = InlineMetadata(INLINE_CONTENT)
|
||||||
|
assert inline.rename("key1", "new key") is True
|
||||||
|
assert "key1" not in inline.dict
|
||||||
|
assert inline.dict["new key"] == ["value1", "value2", "value3"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_inline_metadata_rename_4():
|
||||||
|
"""Test InlineMetadata rename() method.
|
||||||
|
|
||||||
|
GIVEN a InlineMetadata object
|
||||||
|
WHEN the rename() method is called with an existing key and value
|
||||||
|
THEN return True and rename the value
|
||||||
|
"""
|
||||||
|
inline = InlineMetadata(INLINE_CONTENT)
|
||||||
|
assert inline.rename("key1", "value1", "new value") is True
|
||||||
|
assert "value1" not in inline.dict["key1"]
|
||||||
|
assert "new value" in inline.dict["key1"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_inline_metadata_rename_5():
|
||||||
|
"""Test InlineMetadata rename() method.
|
||||||
|
|
||||||
|
GIVEN a InlineMetadata object
|
||||||
|
WHEN the rename() method is called with an existing key and value and the new value already exists
|
||||||
|
THEN return True and remove the old value leaving one instance of the new value
|
||||||
|
"""
|
||||||
|
inline = InlineMetadata(INLINE_CONTENT)
|
||||||
|
assert inline.rename("key1", "value1", "value2") is True
|
||||||
|
assert inline.dict["key1"] == ["value2", "value3"]
|
||||||
@@ -6,8 +6,6 @@ import pytest
|
|||||||
|
|
||||||
from obsidian_metadata.models.enums import MetadataType
|
from obsidian_metadata.models.enums import MetadataType
|
||||||
from obsidian_metadata.models.metadata import (
|
from obsidian_metadata.models.metadata import (
|
||||||
Frontmatter,
|
|
||||||
InlineMetadata,
|
|
||||||
InlineTags,
|
InlineTags,
|
||||||
VaultMetadata,
|
VaultMetadata,
|
||||||
)
|
)
|
||||||
@@ -68,514 +66,6 @@ repeated_key:: repeated_key_value2
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def test_frontmatter_create_1() -> None:
|
|
||||||
"""Test frontmatter creation.
|
|
||||||
|
|
||||||
GIVEN valid frontmatter content
|
|
||||||
WHEN a Frontmatter object is created
|
|
||||||
THEN parse the YAML frontmatter and add it to the object
|
|
||||||
"""
|
|
||||||
frontmatter = Frontmatter(INLINE_CONTENT)
|
|
||||||
assert frontmatter.dict == {}
|
|
||||||
|
|
||||||
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
|
||||||
assert frontmatter.dict == {
|
|
||||||
"frontmatter_Key1": ["frontmatter_Key1_value"],
|
|
||||||
"frontmatter_Key2": ["article", "note"],
|
|
||||||
"shared_key1": ["shared_key1_value"],
|
|
||||||
"tags": ["tag_1", "tag_2", "📅/tag_3"],
|
|
||||||
}
|
|
||||||
assert frontmatter.dict_original == {
|
|
||||||
"frontmatter_Key1": ["frontmatter_Key1_value"],
|
|
||||||
"frontmatter_Key2": ["article", "note"],
|
|
||||||
"shared_key1": ["shared_key1_value"],
|
|
||||||
"tags": ["tag_1", "tag_2", "📅/tag_3"],
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def test_frontmatter_create_2() -> None:
|
|
||||||
"""Test frontmatter creation error.
|
|
||||||
|
|
||||||
GIVEN invalid frontmatter content
|
|
||||||
WHEN a Frontmatter object is created
|
|
||||||
THEN raise ValueError
|
|
||||||
"""
|
|
||||||
fn = """---
|
|
||||||
tags: tag
|
|
||||||
invalid = = "content"
|
|
||||||
---
|
|
||||||
"""
|
|
||||||
with pytest.raises(AttributeError):
|
|
||||||
Frontmatter(fn)
|
|
||||||
|
|
||||||
|
|
||||||
def test_frontmatter_create_3():
|
|
||||||
"""Test frontmatter creation error.
|
|
||||||
|
|
||||||
GIVEN empty frontmatter content
|
|
||||||
WHEN a Frontmatter object is created
|
|
||||||
THEN set the dict to an empty dict
|
|
||||||
"""
|
|
||||||
content = "---\n\n---"
|
|
||||||
frontmatter = Frontmatter(content)
|
|
||||||
assert frontmatter.dict == {}
|
|
||||||
|
|
||||||
|
|
||||||
def test_frontmatter_create_4():
|
|
||||||
"""Test frontmatter creation error.
|
|
||||||
|
|
||||||
GIVEN empty frontmatter content with a yaml marker
|
|
||||||
WHEN a Frontmatter object is created
|
|
||||||
THEN set the dict to an empty dict
|
|
||||||
"""
|
|
||||||
content = "---\n-\n---"
|
|
||||||
frontmatter = Frontmatter(content)
|
|
||||||
assert frontmatter.dict == {}
|
|
||||||
|
|
||||||
|
|
||||||
def test_frontmatter_add_1():
|
|
||||||
"""Test frontmatter add() method.
|
|
||||||
|
|
||||||
GIVEN a Frontmatter object
|
|
||||||
WHEN the add() method is called with an existing key
|
|
||||||
THEN return False
|
|
||||||
"""
|
|
||||||
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
|
||||||
|
|
||||||
assert frontmatter.add("frontmatter_Key1") is False
|
|
||||||
|
|
||||||
|
|
||||||
def test_frontmatter_add_2():
|
|
||||||
"""Test frontmatter add() method.
|
|
||||||
|
|
||||||
GIVEN a Frontmatter object
|
|
||||||
WHEN the add() method is called with an existing key and existing value
|
|
||||||
THEN return False
|
|
||||||
"""
|
|
||||||
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
|
||||||
assert frontmatter.add("frontmatter_Key1", "frontmatter_Key1_value") is False
|
|
||||||
|
|
||||||
|
|
||||||
def test_frontmatter_add_3():
|
|
||||||
"""Test frontmatter add() method.
|
|
||||||
|
|
||||||
GIVEN a Frontmatter object
|
|
||||||
WHEN the add() method is called with a new key
|
|
||||||
THEN return True and add the key to the dict
|
|
||||||
"""
|
|
||||||
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
|
||||||
assert frontmatter.add("added_key") is True
|
|
||||||
assert "added_key" in frontmatter.dict
|
|
||||||
|
|
||||||
|
|
||||||
def test_frontmatter_add_4():
|
|
||||||
"""Test frontmatter add() method.
|
|
||||||
|
|
||||||
GIVEN a Frontmatter object
|
|
||||||
WHEN the add() method is called with a new key and a new value
|
|
||||||
THEN return True and add the key and the value to the dict
|
|
||||||
"""
|
|
||||||
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
|
||||||
assert frontmatter.add("added_key", "added_value") is True
|
|
||||||
assert frontmatter.dict["added_key"] == ["added_value"]
|
|
||||||
|
|
||||||
|
|
||||||
def test_frontmatter_add_5():
|
|
||||||
"""Test frontmatter add() method.
|
|
||||||
|
|
||||||
GIVEN a Frontmatter object
|
|
||||||
WHEN the add() method is called with an existing key and a new value
|
|
||||||
THEN return True and add the value to the dict
|
|
||||||
"""
|
|
||||||
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
|
||||||
assert frontmatter.add("frontmatter_Key1", "new_value") is True
|
|
||||||
assert frontmatter.dict["frontmatter_Key1"] == ["frontmatter_Key1_value", "new_value"]
|
|
||||||
|
|
||||||
|
|
||||||
def test_frontmatter_add_6():
|
|
||||||
"""Test frontmatter add() method.
|
|
||||||
|
|
||||||
GIVEN a Frontmatter object
|
|
||||||
WHEN the add() method is called with an existing key and a list of new values
|
|
||||||
THEN return True and add the values to the dict
|
|
||||||
"""
|
|
||||||
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
|
||||||
assert frontmatter.add("frontmatter_Key1", ["new_value", "new_value2"]) is True
|
|
||||||
assert frontmatter.dict["frontmatter_Key1"] == [
|
|
||||||
"frontmatter_Key1_value",
|
|
||||||
"new_value",
|
|
||||||
"new_value2",
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def test_frontmatter_add_7():
|
|
||||||
"""Test frontmatter add() method.
|
|
||||||
|
|
||||||
GIVEN a Frontmatter object
|
|
||||||
WHEN the add() method is called with an existing key and a list of values including an existing value
|
|
||||||
THEN return True and add the new values to the dict
|
|
||||||
"""
|
|
||||||
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
|
||||||
assert (
|
|
||||||
frontmatter.add("frontmatter_Key1", ["frontmatter_Key1_value", "new_value", "new_value2"])
|
|
||||||
is True
|
|
||||||
)
|
|
||||||
assert frontmatter.dict["frontmatter_Key1"] == [
|
|
||||||
"frontmatter_Key1_value",
|
|
||||||
"new_value",
|
|
||||||
"new_value2",
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def test_frontmatter_contains_1():
|
|
||||||
"""Test frontmatter contains() method.
|
|
||||||
|
|
||||||
GIVEN a Frontmatter object
|
|
||||||
WHEN the contains() method is called with a key
|
|
||||||
THEN return True if the key is found
|
|
||||||
"""
|
|
||||||
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
|
||||||
assert frontmatter.contains("frontmatter_Key1") is True
|
|
||||||
|
|
||||||
|
|
||||||
def test_frontmatter_contains_2():
|
|
||||||
"""Test frontmatter contains() method.
|
|
||||||
|
|
||||||
GIVEN a Frontmatter object
|
|
||||||
WHEN the contains() method is called with a key
|
|
||||||
THEN return False if the key is not found
|
|
||||||
"""
|
|
||||||
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
|
||||||
assert frontmatter.contains("no_key") is False
|
|
||||||
|
|
||||||
|
|
||||||
def test_frontmatter_contains_3():
|
|
||||||
"""Test frontmatter contains() method.
|
|
||||||
|
|
||||||
GIVEN a Frontmatter object
|
|
||||||
WHEN the contains() method is called with a key and a value
|
|
||||||
THEN return True if the key and value is found
|
|
||||||
"""
|
|
||||||
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
|
||||||
assert frontmatter.contains("frontmatter_Key2", "article") is True
|
|
||||||
|
|
||||||
|
|
||||||
def test_frontmatter_contains_4():
|
|
||||||
"""Test frontmatter contains() method.
|
|
||||||
|
|
||||||
GIVEN a Frontmatter object
|
|
||||||
WHEN the contains() method is called with a key and a value
|
|
||||||
THEN return False if the key and value is not found
|
|
||||||
"""
|
|
||||||
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
|
||||||
assert frontmatter.contains("frontmatter_Key2", "no value") is False
|
|
||||||
|
|
||||||
|
|
||||||
def test_frontmatter_contains_5():
|
|
||||||
"""Test frontmatter contains() method.
|
|
||||||
|
|
||||||
GIVEN a Frontmatter object
|
|
||||||
WHEN the contains() method is called with a key regex
|
|
||||||
THEN return True if a key matches the regex
|
|
||||||
"""
|
|
||||||
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
|
||||||
assert frontmatter.contains(r"\d$", is_regex=True) is True
|
|
||||||
|
|
||||||
|
|
||||||
def test_frontmatter_contains_6():
|
|
||||||
"""Test frontmatter contains() method.
|
|
||||||
|
|
||||||
GIVEN a Frontmatter object
|
|
||||||
WHEN the contains() method is called with a key regex
|
|
||||||
THEN return False if no key matches the regex
|
|
||||||
"""
|
|
||||||
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
|
||||||
assert frontmatter.contains(r"^\d", is_regex=True) is False
|
|
||||||
|
|
||||||
|
|
||||||
def test_frontmatter_contains_7():
|
|
||||||
"""Test frontmatter contains() method.
|
|
||||||
|
|
||||||
GIVEN a Frontmatter object
|
|
||||||
WHEN the contains() method is called with a key and value regex
|
|
||||||
THEN return True if a value matches the regex
|
|
||||||
"""
|
|
||||||
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
|
||||||
assert frontmatter.contains("key", r"\w\d_", is_regex=True) is True
|
|
||||||
|
|
||||||
|
|
||||||
def test_frontmatter_contains_8():
|
|
||||||
"""Test frontmatter contains() method.
|
|
||||||
|
|
||||||
GIVEN a Frontmatter object
|
|
||||||
WHEN the contains() method is called with a key and value regex
|
|
||||||
THEN return False if a value does not match the regex
|
|
||||||
"""
|
|
||||||
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
|
||||||
assert frontmatter.contains("key", r"_\d", is_regex=True) is False
|
|
||||||
|
|
||||||
|
|
||||||
def test_frontmatter_rename() -> None:
|
|
||||||
"""Test frontmatter rename."""
|
|
||||||
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
|
||||||
assert frontmatter.dict == {
|
|
||||||
"frontmatter_Key1": ["frontmatter_Key1_value"],
|
|
||||||
"frontmatter_Key2": ["article", "note"],
|
|
||||||
"shared_key1": ["shared_key1_value"],
|
|
||||||
"tags": ["tag_1", "tag_2", "📅/tag_3"],
|
|
||||||
}
|
|
||||||
|
|
||||||
assert frontmatter.rename("no key", "new key") is False
|
|
||||||
assert frontmatter.rename("tags", "no tag", "new key") is False
|
|
||||||
|
|
||||||
assert frontmatter.has_changes() is False
|
|
||||||
assert frontmatter.rename("tags", "tag_2", "new tag") is True
|
|
||||||
|
|
||||||
assert frontmatter.dict["tags"] == ["new tag", "tag_1", "📅/tag_3"]
|
|
||||||
assert frontmatter.rename("tags", "old_tags") is True
|
|
||||||
assert frontmatter.dict["old_tags"] == ["new tag", "tag_1", "📅/tag_3"]
|
|
||||||
assert "tags" not in frontmatter.dict
|
|
||||||
|
|
||||||
assert frontmatter.has_changes() is True
|
|
||||||
|
|
||||||
|
|
||||||
def test_frontmatter_delete() -> None:
|
|
||||||
"""Test Frontmatter delete method."""
|
|
||||||
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
|
||||||
assert frontmatter.dict == {
|
|
||||||
"frontmatter_Key1": ["frontmatter_Key1_value"],
|
|
||||||
"frontmatter_Key2": ["article", "note"],
|
|
||||||
"shared_key1": ["shared_key1_value"],
|
|
||||||
"tags": ["tag_1", "tag_2", "📅/tag_3"],
|
|
||||||
}
|
|
||||||
|
|
||||||
assert frontmatter.delete("no key") is False
|
|
||||||
assert frontmatter.delete("tags", "no value") is False
|
|
||||||
assert frontmatter.delete(r"\d{3}") is False
|
|
||||||
assert frontmatter.has_changes() is False
|
|
||||||
assert frontmatter.delete("tags", "tag_2") is True
|
|
||||||
assert frontmatter.dict["tags"] == ["tag_1", "📅/tag_3"]
|
|
||||||
assert frontmatter.delete("tags") is True
|
|
||||||
assert "tags" not in frontmatter.dict
|
|
||||||
assert frontmatter.has_changes() is True
|
|
||||||
assert frontmatter.delete("shared_key1", r"\w+") is True
|
|
||||||
assert frontmatter.dict["shared_key1"] == []
|
|
||||||
assert frontmatter.delete(r"\w.tter") is True
|
|
||||||
assert frontmatter.dict == {"shared_key1": []}
|
|
||||||
|
|
||||||
|
|
||||||
def test_frontmatter_delete_all():
|
|
||||||
"""Test Frontmatter delete_all method.
|
|
||||||
|
|
||||||
GIVEN Frontmatter with multiple keys
|
|
||||||
WHEN delete_all is called
|
|
||||||
THEN all keys and values are deleted
|
|
||||||
"""
|
|
||||||
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
|
||||||
frontmatter.delete_all()
|
|
||||||
assert frontmatter.dict == {}
|
|
||||||
|
|
||||||
|
|
||||||
def test_frontmatter_yaml_conversion():
|
|
||||||
"""Test Frontmatter to_yaml method."""
|
|
||||||
new_frontmatter: str = """\
|
|
||||||
tags:
|
|
||||||
- tag_1
|
|
||||||
- tag_2
|
|
||||||
- 📅/tag_3
|
|
||||||
frontmatter_Key1: frontmatter_Key1_value
|
|
||||||
frontmatter_Key2:
|
|
||||||
- article
|
|
||||||
- note
|
|
||||||
shared_key1: shared_key1_value
|
|
||||||
"""
|
|
||||||
new_frontmatter_sorted: str = """\
|
|
||||||
frontmatter_Key1: frontmatter_Key1_value
|
|
||||||
frontmatter_Key2:
|
|
||||||
- article
|
|
||||||
- note
|
|
||||||
shared_key1: shared_key1_value
|
|
||||||
tags:
|
|
||||||
- tag_1
|
|
||||||
- tag_2
|
|
||||||
- 📅/tag_3
|
|
||||||
"""
|
|
||||||
frontmatter = Frontmatter(FRONTMATTER_CONTENT)
|
|
||||||
assert frontmatter.to_yaml() == new_frontmatter
|
|
||||||
assert frontmatter.to_yaml(sort_keys=True) == new_frontmatter_sorted
|
|
||||||
|
|
||||||
|
|
||||||
def test_inline_metadata_add() -> None:
|
|
||||||
"""Test inline add."""
|
|
||||||
inline = InlineMetadata(INLINE_CONTENT)
|
|
||||||
|
|
||||||
assert inline.add("bold_key1") is False
|
|
||||||
assert inline.add("bold_key1", "bold_key1_value") is False
|
|
||||||
assert inline.add("added_key") is True
|
|
||||||
assert inline.dict == {
|
|
||||||
"added_key": [],
|
|
||||||
"bold_key1": ["bold_key1_value"],
|
|
||||||
"bold_key2": ["bold_key2_value"],
|
|
||||||
"emoji_📅_key": ["emoji_📅_key_value"],
|
|
||||||
"in_text_key1": ["in_text_key1_value"],
|
|
||||||
"in_text_key2": ["in_text_key2_value"],
|
|
||||||
"link_key": ["link_key_value"],
|
|
||||||
"repeated_key": ["repeated_key_value1", "repeated_key_value2"],
|
|
||||||
"tag_key": ["tag_key_value"],
|
|
||||||
}
|
|
||||||
|
|
||||||
assert inline.add("added_key1", "added_value") is True
|
|
||||||
assert inline.dict == {
|
|
||||||
"added_key": [],
|
|
||||||
"added_key1": ["added_value"],
|
|
||||||
"bold_key1": ["bold_key1_value"],
|
|
||||||
"bold_key2": ["bold_key2_value"],
|
|
||||||
"emoji_📅_key": ["emoji_📅_key_value"],
|
|
||||||
"in_text_key1": ["in_text_key1_value"],
|
|
||||||
"in_text_key2": ["in_text_key2_value"],
|
|
||||||
"link_key": ["link_key_value"],
|
|
||||||
"repeated_key": ["repeated_key_value1", "repeated_key_value2"],
|
|
||||||
"tag_key": ["tag_key_value"],
|
|
||||||
}
|
|
||||||
|
|
||||||
assert inline.dict == {
|
|
||||||
"added_key": [],
|
|
||||||
"added_key1": ["added_value"],
|
|
||||||
"bold_key1": ["bold_key1_value"],
|
|
||||||
"bold_key2": ["bold_key2_value"],
|
|
||||||
"emoji_📅_key": ["emoji_📅_key_value"],
|
|
||||||
"in_text_key1": ["in_text_key1_value"],
|
|
||||||
"in_text_key2": ["in_text_key2_value"],
|
|
||||||
"link_key": ["link_key_value"],
|
|
||||||
"repeated_key": ["repeated_key_value1", "repeated_key_value2"],
|
|
||||||
"tag_key": ["tag_key_value"],
|
|
||||||
}
|
|
||||||
|
|
||||||
assert inline.add("added_key", "added_value")
|
|
||||||
assert inline.dict == {
|
|
||||||
"added_key": ["added_value"],
|
|
||||||
"added_key1": ["added_value"],
|
|
||||||
"bold_key1": ["bold_key1_value"],
|
|
||||||
"bold_key2": ["bold_key2_value"],
|
|
||||||
"emoji_📅_key": ["emoji_📅_key_value"],
|
|
||||||
"in_text_key1": ["in_text_key1_value"],
|
|
||||||
"in_text_key2": ["in_text_key2_value"],
|
|
||||||
"link_key": ["link_key_value"],
|
|
||||||
"repeated_key": ["repeated_key_value1", "repeated_key_value2"],
|
|
||||||
"tag_key": ["tag_key_value"],
|
|
||||||
}
|
|
||||||
assert inline.add("repeated_key", "repeated_key_value1") is False
|
|
||||||
assert inline.add("repeated_key", "new_value") is True
|
|
||||||
|
|
||||||
|
|
||||||
def test_inline_metadata_contains() -> None:
|
|
||||||
"""Test inline metadata contains method."""
|
|
||||||
inline = InlineMetadata(INLINE_CONTENT)
|
|
||||||
|
|
||||||
assert inline.contains("bold_key1") is True
|
|
||||||
assert inline.contains("bold_key2", "bold_key2_value") is True
|
|
||||||
assert inline.contains("bold_key3") is False
|
|
||||||
assert inline.contains("bold_key2", "no value") is False
|
|
||||||
|
|
||||||
assert inline.contains(r"\w{4}_key", is_regex=True) is True
|
|
||||||
assert inline.contains(r"^\d", is_regex=True) is False
|
|
||||||
assert inline.contains("1$", r"\d_value", is_regex=True) is True
|
|
||||||
assert inline.contains("key", r"^\d_value", is_regex=True) is False
|
|
||||||
|
|
||||||
|
|
||||||
def test_inline_metadata_create() -> None:
|
|
||||||
"""Test inline metadata creation."""
|
|
||||||
inline = InlineMetadata(FRONTMATTER_CONTENT)
|
|
||||||
assert inline.dict == {}
|
|
||||||
inline = InlineMetadata(INLINE_CONTENT)
|
|
||||||
assert inline.dict == {
|
|
||||||
"bold_key1": ["bold_key1_value"],
|
|
||||||
"bold_key2": ["bold_key2_value"],
|
|
||||||
"emoji_📅_key": ["emoji_📅_key_value"],
|
|
||||||
"in_text_key1": ["in_text_key1_value"],
|
|
||||||
"in_text_key2": ["in_text_key2_value"],
|
|
||||||
"link_key": ["link_key_value"],
|
|
||||||
"repeated_key": ["repeated_key_value1", "repeated_key_value2"],
|
|
||||||
"tag_key": ["tag_key_value"],
|
|
||||||
}
|
|
||||||
assert inline.dict_original == {
|
|
||||||
"bold_key1": ["bold_key1_value"],
|
|
||||||
"bold_key2": ["bold_key2_value"],
|
|
||||||
"emoji_📅_key": ["emoji_📅_key_value"],
|
|
||||||
"in_text_key1": ["in_text_key1_value"],
|
|
||||||
"in_text_key2": ["in_text_key2_value"],
|
|
||||||
"link_key": ["link_key_value"],
|
|
||||||
"repeated_key": ["repeated_key_value1", "repeated_key_value2"],
|
|
||||||
"tag_key": ["tag_key_value"],
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def test_inline_metadata_delete() -> None:
|
|
||||||
"""Test inline metadata delete."""
|
|
||||||
inline = InlineMetadata(INLINE_CONTENT)
|
|
||||||
assert inline.dict == {
|
|
||||||
"bold_key1": ["bold_key1_value"],
|
|
||||||
"bold_key2": ["bold_key2_value"],
|
|
||||||
"emoji_📅_key": ["emoji_📅_key_value"],
|
|
||||||
"in_text_key1": ["in_text_key1_value"],
|
|
||||||
"in_text_key2": ["in_text_key2_value"],
|
|
||||||
"link_key": ["link_key_value"],
|
|
||||||
"repeated_key": ["repeated_key_value1", "repeated_key_value2"],
|
|
||||||
"tag_key": ["tag_key_value"],
|
|
||||||
}
|
|
||||||
|
|
||||||
assert inline.delete("no key") is False
|
|
||||||
assert inline.delete("repeated_key", "no value") is False
|
|
||||||
assert inline.has_changes() is False
|
|
||||||
assert inline.delete("repeated_key", "repeated_key_value1") is True
|
|
||||||
assert inline.dict["repeated_key"] == ["repeated_key_value2"]
|
|
||||||
assert inline.delete("repeated_key") is True
|
|
||||||
assert "repeated_key" not in inline.dict
|
|
||||||
assert inline.has_changes() is True
|
|
||||||
assert inline.delete(r"\d{3}") is False
|
|
||||||
assert inline.delete(r"bold_key\d") is True
|
|
||||||
assert inline.dict == {
|
|
||||||
"emoji_📅_key": ["emoji_📅_key_value"],
|
|
||||||
"in_text_key1": ["in_text_key1_value"],
|
|
||||||
"in_text_key2": ["in_text_key2_value"],
|
|
||||||
"link_key": ["link_key_value"],
|
|
||||||
"tag_key": ["tag_key_value"],
|
|
||||||
}
|
|
||||||
assert inline.delete("emoji_📅_key", ".*📅.*") is True
|
|
||||||
assert inline.dict == {
|
|
||||||
"emoji_📅_key": [],
|
|
||||||
"in_text_key1": ["in_text_key1_value"],
|
|
||||||
"in_text_key2": ["in_text_key2_value"],
|
|
||||||
"link_key": ["link_key_value"],
|
|
||||||
"tag_key": ["tag_key_value"],
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def test_inline_metadata_rename() -> None:
|
|
||||||
"""Test inline metadata rename."""
|
|
||||||
inline = InlineMetadata(INLINE_CONTENT)
|
|
||||||
assert inline.dict == {
|
|
||||||
"bold_key1": ["bold_key1_value"],
|
|
||||||
"bold_key2": ["bold_key2_value"],
|
|
||||||
"emoji_📅_key": ["emoji_📅_key_value"],
|
|
||||||
"in_text_key1": ["in_text_key1_value"],
|
|
||||||
"in_text_key2": ["in_text_key2_value"],
|
|
||||||
"link_key": ["link_key_value"],
|
|
||||||
"repeated_key": ["repeated_key_value1", "repeated_key_value2"],
|
|
||||||
"tag_key": ["tag_key_value"],
|
|
||||||
}
|
|
||||||
|
|
||||||
assert inline.rename("no key", "new key") is False
|
|
||||||
assert inline.rename("repeated_key", "no value", "new key") is False
|
|
||||||
assert inline.has_changes() is False
|
|
||||||
assert inline.rename("repeated_key", "repeated_key_value1", "new value") is True
|
|
||||||
assert inline.dict["repeated_key"] == ["new value", "repeated_key_value2"]
|
|
||||||
assert inline.rename("repeated_key", "old_key") is True
|
|
||||||
assert inline.dict["old_key"] == ["new value", "repeated_key_value2"]
|
|
||||||
assert "repeated_key" not in inline.dict
|
|
||||||
assert inline.has_changes() is True
|
|
||||||
|
|
||||||
|
|
||||||
def test_inline_tags_add() -> None:
|
def test_inline_tags_add() -> None:
|
||||||
"""Test inline tags add."""
|
"""Test inline tags add."""
|
||||||
tags = InlineTags(INLINE_CONTENT)
|
tags = InlineTags(INLINE_CONTENT)
|
||||||
|
|||||||
@@ -6,17 +6,7 @@ import pytest
|
|||||||
from obsidian_metadata.models.patterns import Patterns
|
from obsidian_metadata.models.patterns import Patterns
|
||||||
|
|
||||||
TAG_CONTENT: str = "#1 #2 **#3** [[#4]] [[#5|test]] #6#notag #7_8 #9/10 #11-12 #13; #14, #15. #16: #17* #18(#19) #20[#21] #22\\ #23& #24# #25 **#26** #📅/tag [link](#no_tag) https://example.com/somepage.html_#no_url_tags"
|
TAG_CONTENT: str = "#1 #2 **#3** [[#4]] [[#5|test]] #6#notag #7_8 #9/10 #11-12 #13; #14, #15. #16: #17* #18(#19) #20[#21] #22\\ #23& #24# #25 **#26** #📅/tag [link](#no_tag) https://example.com/somepage.html_#no_url_tags"
|
||||||
INLINE_METADATA: str = """
|
|
||||||
**1:: 1**
|
|
||||||
2_2:: [[2_2]] | 2
|
|
||||||
asdfasdf [3:: 3] asdfasdf [7::7] asdf
|
|
||||||
[4:: 4] [5:: 5]
|
|
||||||
> 6:: 6
|
|
||||||
**8**:: **8**
|
|
||||||
10::
|
|
||||||
📅11:: 11/📅/11
|
|
||||||
emoji_📅_key:: 📅emoji_📅_key_value
|
|
||||||
"""
|
|
||||||
FRONTMATTER_CONTENT: str = """
|
FRONTMATTER_CONTENT: str = """
|
||||||
---
|
---
|
||||||
tags:
|
tags:
|
||||||
@@ -150,17 +140,64 @@ def test_find_inline_tags():
|
|||||||
def test_find_inline_metadata():
|
def test_find_inline_metadata():
|
||||||
"""Test find_inline_metadata regex."""
|
"""Test find_inline_metadata regex."""
|
||||||
pattern = Patterns()
|
pattern = Patterns()
|
||||||
|
content = """
|
||||||
|
**1:: 1**
|
||||||
|
2_2:: [[2_2]] | 2
|
||||||
|
asdfasdf [3:: 3] asdfasdf [7::7] asdf
|
||||||
|
[4:: 4] [5:: 5]
|
||||||
|
> 6:: 6
|
||||||
|
**8**:: **8**
|
||||||
|
10::
|
||||||
|
📅11:: 11/📅/11
|
||||||
|
emoji_📅_key::emoji_📅_key_value
|
||||||
|
key1:: value1
|
||||||
|
key1:: value2
|
||||||
|
key1:: value3
|
||||||
|
indented_key:: value1
|
||||||
|
Paragraph of text with an [inline_key:: value1] and [inline_key:: value2] and [inline_key:: value3] which should do it.
|
||||||
|
> blockquote_key:: value1
|
||||||
|
> blockquote_key:: value2
|
||||||
|
|
||||||
result = pattern.find_inline_metadata.findall(INLINE_METADATA)
|
- list_key:: value1
|
||||||
|
- list_key:: [[value2]]
|
||||||
|
|
||||||
|
1. list_key:: value1
|
||||||
|
2. list_key:: value2
|
||||||
|
|
||||||
|
| table_key:: value1 | table_key:: value2 |
|
||||||
|
---
|
||||||
|
frontmatter_key1: frontmatter_key1_value
|
||||||
|
---
|
||||||
|
not_a_key: not_a_value
|
||||||
|
paragraph metadata:: key in text
|
||||||
|
"""
|
||||||
|
|
||||||
|
result = pattern.find_inline_metadata.findall(content)
|
||||||
assert result == [
|
assert result == [
|
||||||
("", "", "1", "1**"),
|
("", "", "1", "1**"),
|
||||||
("", "", "2_2", "[[2_2]] | 2"),
|
("", "", "2_2", "[[2_2]] | 2"),
|
||||||
("3", "3", "", ""),
|
("3", "3", "", ""),
|
||||||
("7", "7", "", ""),
|
("7", "7", "", ""),
|
||||||
("", "", "4", "4] [5:: 5]"),
|
("", "", "4", "4] [5:: 5]"),
|
||||||
|
("", "", "6", "6"),
|
||||||
("", "", "8**", "**8**"),
|
("", "", "8**", "**8**"),
|
||||||
("", "", "11", "11/📅/11"),
|
("", "", "11", "11/📅/11"),
|
||||||
("", "", "emoji_📅_key", "📅emoji_📅_key_value"),
|
("", "", "emoji_📅_key", "emoji_📅_key_value"),
|
||||||
|
("", "", "key1", "value1"),
|
||||||
|
("", "", "key1", "value2"),
|
||||||
|
("", "", "key1", "value3"),
|
||||||
|
("", "", "indented_key", "value1"),
|
||||||
|
("inline_key", "value1", "", ""),
|
||||||
|
("inline_key", "value2", "", ""),
|
||||||
|
("inline_key", "value3", "", ""),
|
||||||
|
("", "", "blockquote_key", "value1"),
|
||||||
|
("", "", "blockquote_key", "value2"),
|
||||||
|
("", "", "list_key", "value1"),
|
||||||
|
("", "", "list_key", "[[value2]]"),
|
||||||
|
("", "", "list_key", "value1"),
|
||||||
|
("", "", "list_key", "value2"),
|
||||||
|
("", "", "table_key", "value1 | table_key:: value2 |"),
|
||||||
|
("", "", "metadata", "key in text"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user