mirror of
https://github.com/natelandau/obsidian-metadata.git
synced 2025-11-08 05:03:47 -05:00
refactor: cleanup rename and delete from dict functions
This commit is contained in:
@@ -5,12 +5,14 @@ from obsidian_metadata._utils.alerts import LoggerManager
|
||||
from obsidian_metadata._utils.utilities import (
|
||||
clean_dictionary,
|
||||
clear_screen,
|
||||
delete_from_dict,
|
||||
dict_contains,
|
||||
dict_keys_to_lower,
|
||||
dict_values_to_lists_strings,
|
||||
docstring_parameter,
|
||||
merge_dictionaries,
|
||||
remove_markdown_sections,
|
||||
rename_in_dict,
|
||||
validate_csv_bulk_imports,
|
||||
version_callback,
|
||||
)
|
||||
@@ -19,12 +21,14 @@ __all__ = [
|
||||
"alerts",
|
||||
"clean_dictionary",
|
||||
"clear_screen",
|
||||
"delete_from_dict",
|
||||
"dict_contains",
|
||||
"dict_keys_to_lower",
|
||||
"dict_values_to_lists_strings",
|
||||
"docstring_parameter",
|
||||
"LoggerManager",
|
||||
"merge_dictionaries",
|
||||
"rename_in_dict",
|
||||
"remove_markdown_sections",
|
||||
"validate_csv_bulk_imports",
|
||||
"version_callback",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
"""Utility functions."""
|
||||
import copy
|
||||
import csv
|
||||
import re
|
||||
from os import name, system
|
||||
@@ -118,6 +119,48 @@ def dict_values_to_lists_strings(
|
||||
return new_dict
|
||||
|
||||
|
||||
def delete_from_dict( # noqa: C901
|
||||
dictionary: dict, key: str, value: str = None, is_regex: bool = False
|
||||
) -> dict:
|
||||
"""Delete a key or a value from a dictionary.
|
||||
|
||||
Args:
|
||||
dictionary (dict): Dictionary to delete from
|
||||
is_regex (bool, optional): Whether the key is a regex. Defaults to False.
|
||||
key (str): Key to delete
|
||||
value (str, optional): Value to delete. Defaults to None.
|
||||
|
||||
Returns:
|
||||
dict: Dictionary without the key
|
||||
"""
|
||||
dictionary = copy.deepcopy(dictionary)
|
||||
|
||||
if value is None:
|
||||
if is_regex:
|
||||
return {k: v for k, v in dictionary.items() if not re.search(key, str(k))}
|
||||
|
||||
return {k: v for k, v in dictionary.items() if k != key}
|
||||
|
||||
if is_regex:
|
||||
keys_to_delete = []
|
||||
for _key in dictionary:
|
||||
if re.search(key, str(_key)):
|
||||
if isinstance(dictionary[_key], list):
|
||||
dictionary[_key] = [v for v in dictionary[_key] if not re.search(value, v)]
|
||||
elif isinstance(dictionary[_key], str) and re.search(value, dictionary[_key]):
|
||||
keys_to_delete.append(_key)
|
||||
|
||||
for key in keys_to_delete:
|
||||
dictionary.pop(key)
|
||||
|
||||
elif key in dictionary and isinstance(dictionary[key], list):
|
||||
dictionary[key] = [v for v in dictionary[key] if v != value]
|
||||
elif key in dictionary and dictionary[key] == value:
|
||||
dictionary.pop(key)
|
||||
|
||||
return dictionary
|
||||
|
||||
|
||||
def docstring_parameter(*sub: Any) -> Any:
|
||||
"""Replace variables within docstrings.
|
||||
|
||||
@@ -167,6 +210,31 @@ def merge_dictionaries(dict1: dict, dict2: dict) -> dict:
|
||||
return dict(sorted(dict1.items()))
|
||||
|
||||
|
||||
def rename_in_dict(
|
||||
dictionary: dict[str, list[str]], key: str, value_1: str, value_2: str = None
|
||||
) -> dict:
|
||||
"""Rename a key or a value in a dictionary who's values are lists of strings.
|
||||
|
||||
Args:
|
||||
dictionary (dict): Dictionary to rename in.
|
||||
key (str): Key to check.
|
||||
value_1 (str): `With value_2` this is the value to rename. If `value_2` is None this is the renamed key
|
||||
value_2 (str, Optional): New value.
|
||||
|
||||
Returns:
|
||||
dict: Dictionary with renamed key or value
|
||||
"""
|
||||
dictionary = copy.deepcopy(dictionary)
|
||||
|
||||
if value_2 is None:
|
||||
if key in dictionary and value_1 not in dictionary:
|
||||
dictionary[value_1] = dictionary.pop(key)
|
||||
elif key in dictionary and value_1 in dictionary[key]:
|
||||
dictionary[key] = sorted({value_2 if x == value_1 else x for x in dictionary[key]})
|
||||
|
||||
return dictionary
|
||||
|
||||
|
||||
def remove_markdown_sections(
|
||||
text: str,
|
||||
strip_codeblocks: bool = False,
|
||||
|
||||
@@ -10,10 +10,12 @@ from ruamel.yaml import YAML
|
||||
|
||||
from obsidian_metadata._utils import (
|
||||
clean_dictionary,
|
||||
delete_from_dict,
|
||||
dict_contains,
|
||||
dict_values_to_lists_strings,
|
||||
merge_dictionaries,
|
||||
remove_markdown_sections,
|
||||
rename_in_dict,
|
||||
)
|
||||
from obsidian_metadata._utils.console import console
|
||||
from obsidian_metadata.models import Patterns # isort: ignore
|
||||
@@ -24,7 +26,14 @@ INLINE_TAG_KEY: str = "inline_tag"
|
||||
|
||||
|
||||
class VaultMetadata:
|
||||
"""Representation of all Metadata in the Vault."""
|
||||
"""Representation of all Metadata in the Vault.
|
||||
|
||||
Attributes:
|
||||
dict (dict): Dictionary of all frontmatter and inline metadata. Does not include tags.
|
||||
frontmatter (dict): Dictionary of all frontmatter metadata.
|
||||
inline_metadata (dict): Dictionary of all inline metadata.
|
||||
tags (list): List of all tags.
|
||||
"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.dict: dict[str, list[str]] = {}
|
||||
@@ -59,7 +68,7 @@ class VaultMetadata:
|
||||
self.tags.extend(metadata)
|
||||
self.tags = sorted({s.strip("#") for s in self.tags})
|
||||
|
||||
def contains( # noqa: PLR0911
|
||||
def contains(
|
||||
self, area: MetadataType, key: str = None, value: str = None, is_regex: bool = False
|
||||
) -> bool:
|
||||
"""Check if a key and/or a value exists in the metadata.
|
||||
@@ -82,13 +91,7 @@ class VaultMetadata:
|
||||
|
||||
match area:
|
||||
case MetadataType.ALL:
|
||||
if dict_contains(self.dict, key, value, is_regex):
|
||||
return True
|
||||
if key is None and value is not None:
|
||||
if is_regex:
|
||||
return any(re.search(value, tag) for tag in self.tags)
|
||||
return value in self.tags
|
||||
|
||||
return dict_contains(self.dict, key, value, is_regex)
|
||||
case MetadataType.FRONTMATTER:
|
||||
return dict_contains(self.frontmatter, key, value, is_regex)
|
||||
case MetadataType.INLINE:
|
||||
@@ -102,10 +105,8 @@ class VaultMetadata:
|
||||
return any(re.search(value, tag) for tag in self.tags)
|
||||
return value in self.tags
|
||||
|
||||
return False
|
||||
|
||||
def delete(self, key: str, value_to_delete: str = None) -> bool:
|
||||
"""Delete a key or a key's value from the metadata. Regex is supported to allow deleting more than one key or value.
|
||||
"""Delete a key or a value from the VaultMetadata dict object. Regex is supported to allow deleting more than one key or value.
|
||||
|
||||
Args:
|
||||
key (str): Key to check.
|
||||
@@ -114,17 +115,12 @@ class VaultMetadata:
|
||||
Returns:
|
||||
bool: True if a value was deleted
|
||||
"""
|
||||
new_dict = copy.deepcopy(self.dict)
|
||||
|
||||
if value_to_delete is None:
|
||||
for _k in list(new_dict):
|
||||
if re.search(key, _k):
|
||||
del new_dict[_k]
|
||||
else:
|
||||
for _k, _v in new_dict.items():
|
||||
if re.search(key, _k):
|
||||
new_values = [x for x in _v if not re.search(value_to_delete, x)]
|
||||
new_dict[_k] = sorted(new_values)
|
||||
new_dict = delete_from_dict(
|
||||
dictionary=self.dict,
|
||||
key=key,
|
||||
value=value_to_delete,
|
||||
is_regex=True,
|
||||
)
|
||||
|
||||
if new_dict != self.dict:
|
||||
self.dict = dict(new_dict)
|
||||
@@ -138,28 +134,24 @@ class VaultMetadata:
|
||||
Args:
|
||||
area (MetadataType): Type of metadata to print
|
||||
"""
|
||||
dict_to_print: dict[str, list[str]] = None
|
||||
list_to_print: list[str] = None
|
||||
dict_to_print = None
|
||||
list_to_print = None
|
||||
match area:
|
||||
case MetadataType.INLINE:
|
||||
dict_to_print = self.inline_metadata.copy()
|
||||
dict_to_print = self.inline_metadata
|
||||
header = "All inline metadata"
|
||||
case MetadataType.FRONTMATTER:
|
||||
dict_to_print = self.frontmatter.copy()
|
||||
dict_to_print = self.frontmatter
|
||||
header = "All frontmatter"
|
||||
case MetadataType.TAGS:
|
||||
list_to_print = []
|
||||
for tag in self.tags:
|
||||
list_to_print.append(f"#{tag}")
|
||||
list_to_print = [f"#{x}" for x in self.tags]
|
||||
header = "All inline tags"
|
||||
case MetadataType.KEYS:
|
||||
list_to_print = sorted(self.dict.keys())
|
||||
header = "All Keys"
|
||||
case MetadataType.ALL:
|
||||
dict_to_print = self.dict.copy()
|
||||
list_to_print = []
|
||||
for tag in self.tags:
|
||||
list_to_print.append(f"#{tag}")
|
||||
dict_to_print = self.dict
|
||||
list_to_print = [f"#{x}" for x in self.tags]
|
||||
header = "All metadata"
|
||||
|
||||
if dict_to_print is not None:
|
||||
@@ -189,19 +181,14 @@ class VaultMetadata:
|
||||
key (str): Key to check.
|
||||
value_1 (str): `With value_2` this is the value to rename. If `value_2` is None this is the renamed key
|
||||
value_2 (str, Optional): New value.
|
||||
bypass_check (bool, optional): Bypass the check if the key exists. Defaults to False.
|
||||
|
||||
Returns:
|
||||
bool: True if a value was renamed
|
||||
"""
|
||||
if value_2 is None:
|
||||
if key in self.dict and value_1 not in self.dict:
|
||||
self.dict[value_1] = self.dict.pop(key)
|
||||
return True
|
||||
return False
|
||||
new_dict = rename_in_dict(dictionary=self.dict, key=key, value_1=value_1, value_2=value_2)
|
||||
|
||||
if key in self.dict and value_1 in self.dict[key]:
|
||||
self.dict[key] = sorted({value_2 if x == value_1 else x for x in self.dict[key]})
|
||||
if new_dict != self.dict:
|
||||
self.dict = dict(new_dict)
|
||||
return True
|
||||
|
||||
return False
|
||||
@@ -312,17 +299,12 @@ class Frontmatter:
|
||||
Returns:
|
||||
bool: True if a value was deleted
|
||||
"""
|
||||
new_dict = copy.deepcopy(self.dict)
|
||||
|
||||
if value_to_delete is None:
|
||||
for _k in list(new_dict):
|
||||
if re.search(key, _k):
|
||||
del new_dict[_k]
|
||||
else:
|
||||
for _k, _v in new_dict.items():
|
||||
if re.search(key, _k):
|
||||
new_values = [x for x in _v if not re.search(value_to_delete, x)]
|
||||
new_dict[_k] = sorted(new_values)
|
||||
new_dict = delete_from_dict(
|
||||
dictionary=self.dict,
|
||||
key=key,
|
||||
value=value_to_delete,
|
||||
is_regex=True,
|
||||
)
|
||||
|
||||
if new_dict != self.dict:
|
||||
self.dict = dict(new_dict)
|
||||
@@ -353,14 +335,10 @@ class Frontmatter:
|
||||
Returns:
|
||||
bool: True if a value was renamed
|
||||
"""
|
||||
if value_2 is None:
|
||||
if key in self.dict and value_1 not in self.dict:
|
||||
self.dict[value_1] = self.dict.pop(key)
|
||||
return True
|
||||
return False
|
||||
new_dict = rename_in_dict(dictionary=self.dict, key=key, value_1=value_1, value_2=value_2)
|
||||
|
||||
if key in self.dict and value_1 in self.dict[key]:
|
||||
self.dict[key] = sorted({value_2 if x == value_1 else x for x in self.dict[key]})
|
||||
if new_dict != self.dict:
|
||||
self.dict = dict(new_dict)
|
||||
return True
|
||||
|
||||
return False
|
||||
@@ -491,17 +469,12 @@ class InlineMetadata:
|
||||
Returns:
|
||||
bool: True if a value was deleted
|
||||
"""
|
||||
new_dict = dict(self.dict)
|
||||
|
||||
if value_to_delete is None:
|
||||
for _k in list(new_dict):
|
||||
if re.search(key, _k):
|
||||
del new_dict[_k]
|
||||
else:
|
||||
for _k, _v in new_dict.items():
|
||||
if re.search(key, _k):
|
||||
new_values = [x for x in _v if not re.search(value_to_delete, x)]
|
||||
new_dict[_k] = sorted(new_values)
|
||||
new_dict = delete_from_dict(
|
||||
dictionary=self.dict,
|
||||
key=key,
|
||||
value=value_to_delete,
|
||||
is_regex=True,
|
||||
)
|
||||
|
||||
if new_dict != self.dict:
|
||||
self.dict = dict(new_dict)
|
||||
@@ -528,14 +501,10 @@ class InlineMetadata:
|
||||
Returns:
|
||||
bool: True if a value was renamed
|
||||
"""
|
||||
if value_2 is None:
|
||||
if key in self.dict and value_1 not in self.dict:
|
||||
self.dict[value_1] = self.dict.pop(key)
|
||||
return True
|
||||
return False
|
||||
new_dict = rename_in_dict(dictionary=self.dict, key=key, value_1=value_1, value_2=value_2)
|
||||
|
||||
if key in self.dict and value_1 in self.dict[key]:
|
||||
self.dict[key] = sorted({value_2 if x == value_1 else x for x in self.dict[key]})
|
||||
if new_dict != self.dict:
|
||||
self.dict = dict(new_dict)
|
||||
return True
|
||||
|
||||
return False
|
||||
@@ -580,32 +549,34 @@ class InlineTags:
|
||||
"""Add a new inline tag.
|
||||
|
||||
Args:
|
||||
new_tag (str): Tag to add.
|
||||
new_tag (str, list[str]): Tag to add.
|
||||
|
||||
Returns:
|
||||
bool: True if a tag was added.
|
||||
"""
|
||||
added_tag = False
|
||||
if isinstance(new_tag, list):
|
||||
for _tag in new_tag:
|
||||
if _tag.startswith("#"):
|
||||
_tag = _tag[1:]
|
||||
if _tag in self.list:
|
||||
return False
|
||||
new_list = self.list.copy()
|
||||
new_list.append(_tag)
|
||||
self.list = sorted(new_list)
|
||||
return True
|
||||
else:
|
||||
if new_tag.startswith("#"):
|
||||
new_tag = new_tag[1:]
|
||||
if new_tag in self.list:
|
||||
return False
|
||||
new_list = self.list.copy()
|
||||
new_list.append(new_tag)
|
||||
self.list = sorted(new_list)
|
||||
return True
|
||||
continue
|
||||
self.list.append(_tag)
|
||||
added_tag = True
|
||||
|
||||
return False
|
||||
if added_tag:
|
||||
self.list = sorted(self.list)
|
||||
return True
|
||||
return False
|
||||
|
||||
if new_tag.startswith("#"):
|
||||
new_tag = new_tag[1:]
|
||||
if new_tag in self.list:
|
||||
return False
|
||||
new_list = self.list.copy()
|
||||
new_list.append(new_tag)
|
||||
self.list = sorted(new_list)
|
||||
return True
|
||||
|
||||
def contains(self, tag: str, is_regex: bool = False) -> bool:
|
||||
"""Check if a tag exists in the metadata.
|
||||
@@ -653,13 +624,13 @@ class InlineTags:
|
||||
"""Replace an inline tag with another string.
|
||||
|
||||
Args:
|
||||
old_tag (str): `With value_2` this is the value to rename. If `value_2` is None this is the renamed key
|
||||
new_tag (str, Optional): New value.
|
||||
old_tag (str): `With value_2` this is the value to rename.
|
||||
new_tag (str): New value
|
||||
|
||||
Returns:
|
||||
bool: True if a value was renamed
|
||||
"""
|
||||
if old_tag in self.list:
|
||||
self.list = sorted([new_tag if i == old_tag else i for i in self.list])
|
||||
if old_tag in self.list and new_tag is not None and new_tag:
|
||||
self.list = sorted({new_tag if i == old_tag else i for i in self.list})
|
||||
return True
|
||||
return False
|
||||
|
||||
@@ -47,7 +47,7 @@ repeated_key:: repeated_key_value2
|
||||
"""
|
||||
|
||||
|
||||
def test_frontmatter_create_1() -> None:
|
||||
def test_create_1() -> None:
|
||||
"""Test frontmatter creation.
|
||||
|
||||
GIVEN valid frontmatter content
|
||||
@@ -72,7 +72,7 @@ def test_frontmatter_create_1() -> None:
|
||||
}
|
||||
|
||||
|
||||
def test_frontmatter_create_2() -> None:
|
||||
def test_create_2() -> None:
|
||||
"""Test frontmatter creation error.
|
||||
|
||||
GIVEN invalid frontmatter content
|
||||
@@ -88,7 +88,7 @@ invalid = = "content"
|
||||
Frontmatter(fn)
|
||||
|
||||
|
||||
def test_frontmatter_create_3():
|
||||
def test_create_3():
|
||||
"""Test frontmatter creation error.
|
||||
|
||||
GIVEN empty frontmatter content
|
||||
@@ -100,7 +100,7 @@ def test_frontmatter_create_3():
|
||||
assert frontmatter.dict == {}
|
||||
|
||||
|
||||
def test_frontmatter_create_4():
|
||||
def test_create_4():
|
||||
"""Test frontmatter creation error.
|
||||
|
||||
GIVEN empty frontmatter content with a yaml marker
|
||||
@@ -112,7 +112,7 @@ def test_frontmatter_create_4():
|
||||
assert frontmatter.dict == {}
|
||||
|
||||
|
||||
def test_frontmatter_add_1():
|
||||
def test_add_1():
|
||||
"""Test frontmatter add() method.
|
||||
|
||||
GIVEN a Frontmatter object
|
||||
@@ -124,7 +124,7 @@ def test_frontmatter_add_1():
|
||||
assert frontmatter.add("frontmatter_Key1") is False
|
||||
|
||||
|
||||
def test_frontmatter_add_2():
|
||||
def test_add_2():
|
||||
"""Test frontmatter add() method.
|
||||
|
||||
GIVEN a Frontmatter object
|
||||
@@ -135,7 +135,7 @@ def test_frontmatter_add_2():
|
||||
assert frontmatter.add("frontmatter_Key1", "frontmatter_Key1_value") is False
|
||||
|
||||
|
||||
def test_frontmatter_add_3():
|
||||
def test_add_3():
|
||||
"""Test frontmatter add() method.
|
||||
|
||||
GIVEN a Frontmatter object
|
||||
@@ -147,7 +147,7 @@ def test_frontmatter_add_3():
|
||||
assert "added_key" in frontmatter.dict
|
||||
|
||||
|
||||
def test_frontmatter_add_4():
|
||||
def test_add_4():
|
||||
"""Test frontmatter add() method.
|
||||
|
||||
GIVEN a Frontmatter object
|
||||
@@ -159,7 +159,7 @@ def test_frontmatter_add_4():
|
||||
assert frontmatter.dict["added_key"] == ["added_value"]
|
||||
|
||||
|
||||
def test_frontmatter_add_5():
|
||||
def test_add_5():
|
||||
"""Test frontmatter add() method.
|
||||
|
||||
GIVEN a Frontmatter object
|
||||
@@ -171,7 +171,7 @@ def test_frontmatter_add_5():
|
||||
assert frontmatter.dict["frontmatter_Key1"] == ["frontmatter_Key1_value", "new_value"]
|
||||
|
||||
|
||||
def test_frontmatter_add_6():
|
||||
def test_add_6():
|
||||
"""Test frontmatter add() method.
|
||||
|
||||
GIVEN a Frontmatter object
|
||||
@@ -187,7 +187,7 @@ def test_frontmatter_add_6():
|
||||
]
|
||||
|
||||
|
||||
def test_frontmatter_add_7():
|
||||
def test_add_7():
|
||||
"""Test frontmatter add() method.
|
||||
|
||||
GIVEN a Frontmatter object
|
||||
@@ -206,7 +206,7 @@ def test_frontmatter_add_7():
|
||||
]
|
||||
|
||||
|
||||
def test_frontmatter_contains_1():
|
||||
def test_contains_1():
|
||||
"""Test frontmatter contains() method.
|
||||
|
||||
GIVEN a Frontmatter object
|
||||
@@ -217,7 +217,7 @@ def test_frontmatter_contains_1():
|
||||
assert frontmatter.contains("frontmatter_Key1") is True
|
||||
|
||||
|
||||
def test_frontmatter_contains_2():
|
||||
def test_contains_2():
|
||||
"""Test frontmatter contains() method.
|
||||
|
||||
GIVEN a Frontmatter object
|
||||
@@ -228,7 +228,7 @@ def test_frontmatter_contains_2():
|
||||
assert frontmatter.contains("no_key") is False
|
||||
|
||||
|
||||
def test_frontmatter_contains_3():
|
||||
def test_contains_3():
|
||||
"""Test frontmatter contains() method.
|
||||
|
||||
GIVEN a Frontmatter object
|
||||
@@ -239,7 +239,7 @@ def test_frontmatter_contains_3():
|
||||
assert frontmatter.contains("frontmatter_Key2", "article") is True
|
||||
|
||||
|
||||
def test_frontmatter_contains_4():
|
||||
def test_contains_4():
|
||||
"""Test frontmatter contains() method.
|
||||
|
||||
GIVEN a Frontmatter object
|
||||
@@ -250,7 +250,7 @@ def test_frontmatter_contains_4():
|
||||
assert frontmatter.contains("frontmatter_Key2", "no value") is False
|
||||
|
||||
|
||||
def test_frontmatter_contains_5():
|
||||
def test_contains_5():
|
||||
"""Test frontmatter contains() method.
|
||||
|
||||
GIVEN a Frontmatter object
|
||||
@@ -261,7 +261,7 @@ def test_frontmatter_contains_5():
|
||||
assert frontmatter.contains(r"\d$", is_regex=True) is True
|
||||
|
||||
|
||||
def test_frontmatter_contains_6():
|
||||
def test_contains_6():
|
||||
"""Test frontmatter contains() method.
|
||||
|
||||
GIVEN a Frontmatter object
|
||||
@@ -272,7 +272,7 @@ def test_frontmatter_contains_6():
|
||||
assert frontmatter.contains(r"^\d", is_regex=True) is False
|
||||
|
||||
|
||||
def test_frontmatter_contains_7():
|
||||
def test_contains_7():
|
||||
"""Test frontmatter contains() method.
|
||||
|
||||
GIVEN a Frontmatter object
|
||||
@@ -283,7 +283,7 @@ def test_frontmatter_contains_7():
|
||||
assert frontmatter.contains("key", r"\w\d_", is_regex=True) is True
|
||||
|
||||
|
||||
def test_frontmatter_contains_8():
|
||||
def test_contains_8():
|
||||
"""Test frontmatter contains() method.
|
||||
|
||||
GIVEN a Frontmatter object
|
||||
@@ -294,7 +294,7 @@ def test_frontmatter_contains_8():
|
||||
assert frontmatter.contains("key", r"_\d", is_regex=True) is False
|
||||
|
||||
|
||||
def test_frontmatter_delete_1():
|
||||
def test_delete_1():
|
||||
"""Test frontmatter delete() method.
|
||||
|
||||
GIVEN a Frontmatter object
|
||||
@@ -305,7 +305,7 @@ def test_frontmatter_delete_1():
|
||||
assert frontmatter.delete("no key") is False
|
||||
|
||||
|
||||
def test_frontmatter_delete_2():
|
||||
def test_delete_2():
|
||||
"""Test frontmatter delete() method.
|
||||
|
||||
GIVEN a Frontmatter object
|
||||
@@ -316,7 +316,7 @@ def test_frontmatter_delete_2():
|
||||
assert frontmatter.delete("tags", "no value") is False
|
||||
|
||||
|
||||
def test_frontmatter_delete_3():
|
||||
def test_delete_3():
|
||||
"""Test frontmatter delete() method.
|
||||
|
||||
GIVEN a Frontmatter object
|
||||
@@ -327,7 +327,7 @@ def test_frontmatter_delete_3():
|
||||
assert frontmatter.delete(r"\d{3}") is False
|
||||
|
||||
|
||||
def test_frontmatter_delete_4():
|
||||
def test_delete_4():
|
||||
"""Test frontmatter delete() method.
|
||||
|
||||
GIVEN a Frontmatter object
|
||||
@@ -338,7 +338,7 @@ def test_frontmatter_delete_4():
|
||||
assert frontmatter.delete("tags", r"\d{5}") is False
|
||||
|
||||
|
||||
def test_frontmatter_delete_5():
|
||||
def test_delete_5():
|
||||
"""Test frontmatter delete() method.
|
||||
|
||||
GIVEN a Frontmatter object
|
||||
@@ -351,7 +351,7 @@ def test_frontmatter_delete_5():
|
||||
assert "tags" in frontmatter.dict
|
||||
|
||||
|
||||
def test_frontmatter_delete_6():
|
||||
def test_delete_6():
|
||||
"""Test frontmatter delete() method.
|
||||
|
||||
GIVEN a Frontmatter object
|
||||
@@ -363,7 +363,7 @@ def test_frontmatter_delete_6():
|
||||
assert "tags" not in frontmatter.dict
|
||||
|
||||
|
||||
def test_frontmatter_delete_7():
|
||||
def test_delete_7():
|
||||
"""Test frontmatter delete() method.
|
||||
|
||||
GIVEN a Frontmatter object
|
||||
@@ -376,7 +376,7 @@ def test_frontmatter_delete_7():
|
||||
assert "frontmatter_Key2" not in frontmatter.dict
|
||||
|
||||
|
||||
def test_frontmatter_delete_8():
|
||||
def test_delete_8():
|
||||
"""Test frontmatter delete() method.
|
||||
|
||||
GIVEN a Frontmatter object
|
||||
@@ -390,7 +390,7 @@ def test_frontmatter_delete_8():
|
||||
assert "tag_1" in frontmatter.dict["tags"]
|
||||
|
||||
|
||||
def test_frontmatter_delete_all():
|
||||
def test_delete_all():
|
||||
"""Test Frontmatter delete_all method.
|
||||
|
||||
GIVEN Frontmatter with multiple keys
|
||||
@@ -402,7 +402,7 @@ def test_frontmatter_delete_all():
|
||||
assert frontmatter.dict == {}
|
||||
|
||||
|
||||
def test_frontmatter_has_changes_1():
|
||||
def test_has_changes_1():
|
||||
"""Test frontmatter has_changes() method.
|
||||
|
||||
GIVEN a Frontmatter object
|
||||
@@ -413,7 +413,7 @@ def test_frontmatter_has_changes_1():
|
||||
assert frontmatter.has_changes() is False
|
||||
|
||||
|
||||
def test_frontmatter_has_changes_2():
|
||||
def test_has_changes_2():
|
||||
"""Test frontmatter has_changes() method.
|
||||
|
||||
GIVEN a Frontmatter object
|
||||
@@ -425,7 +425,7 @@ def test_frontmatter_has_changes_2():
|
||||
assert frontmatter.has_changes() is True
|
||||
|
||||
|
||||
def test_frontmatter_rename_1():
|
||||
def test_rename_1():
|
||||
"""Test frontmatter rename() method.
|
||||
|
||||
GIVEN a Frontmatter object
|
||||
@@ -436,7 +436,7 @@ def test_frontmatter_rename_1():
|
||||
assert frontmatter.rename("no key", "new key") is False
|
||||
|
||||
|
||||
def test_frontmatter_rename_2():
|
||||
def test_rename_2():
|
||||
"""Test frontmatter rename() method.
|
||||
|
||||
GIVEN a Frontmatter object
|
||||
@@ -447,7 +447,7 @@ def test_frontmatter_rename_2():
|
||||
assert frontmatter.rename("tags", "no tag", "new key") is False
|
||||
|
||||
|
||||
def test_frontmatter_rename_3():
|
||||
def test_rename_3():
|
||||
"""Test frontmatter rename() method.
|
||||
|
||||
GIVEN a Frontmatter object
|
||||
@@ -460,7 +460,7 @@ def test_frontmatter_rename_3():
|
||||
assert frontmatter.dict["new key"] == ["frontmatter_Key1_value"]
|
||||
|
||||
|
||||
def test_frontmatter_rename_4():
|
||||
def test_rename_4():
|
||||
"""Test frontmatter rename() method.
|
||||
|
||||
GIVEN a Frontmatter object
|
||||
@@ -473,7 +473,7 @@ def test_frontmatter_rename_4():
|
||||
assert "new tag" in frontmatter.dict["tags"]
|
||||
|
||||
|
||||
def test_frontmatter_rename_5():
|
||||
def test_rename_5():
|
||||
"""Test frontmatter rename() method.
|
||||
|
||||
GIVEN a Frontmatter object
|
||||
@@ -486,7 +486,7 @@ def test_frontmatter_rename_5():
|
||||
assert frontmatter.dict["tags"] == ["tag_2", "📅/tag_3"]
|
||||
|
||||
|
||||
def test_frontmatter_to_yaml_1():
|
||||
def test_to_yaml_1():
|
||||
"""Test Frontmatter to_yaml method.
|
||||
|
||||
GIVEN a dictionary
|
||||
@@ -508,7 +508,7 @@ shared_key1: shared_key1_value
|
||||
assert frontmatter.to_yaml() == new_frontmatter
|
||||
|
||||
|
||||
def test_frontmatter_to_yaml_2():
|
||||
def test_to_yaml_2():
|
||||
"""Test Frontmatter to_yaml method.
|
||||
|
||||
GIVEN a dictionary
|
||||
|
||||
@@ -77,7 +77,7 @@ def test__grab_inline_metadata_2():
|
||||
}
|
||||
|
||||
|
||||
def test_inline_metadata_add_1():
|
||||
def test_add_1():
|
||||
"""Test InlineMetadata add() method.
|
||||
|
||||
GIVEN a InlineMetadata object
|
||||
@@ -88,7 +88,7 @@ def test_inline_metadata_add_1():
|
||||
assert inline.add("key1") is False
|
||||
|
||||
|
||||
def test_inline_metadata_add_2():
|
||||
def test_add_2():
|
||||
"""Test InlineMetadata add() method.
|
||||
|
||||
GIVEN a InlineMetadata object
|
||||
@@ -99,7 +99,7 @@ def test_inline_metadata_add_2():
|
||||
assert inline.add("key1", "value1") is False
|
||||
|
||||
|
||||
def test_inline_metadata_add_3():
|
||||
def test_add_3():
|
||||
"""Test InlineMetadata add() method.
|
||||
|
||||
GIVEN a InlineMetadata object
|
||||
@@ -111,7 +111,7 @@ def test_inline_metadata_add_3():
|
||||
assert "added_key" in inline.dict
|
||||
|
||||
|
||||
def test_inline_metadata_add_4():
|
||||
def test_add_4():
|
||||
"""Test InlineMetadata add() method.
|
||||
|
||||
GIVEN a InlineMetadata object
|
||||
@@ -123,7 +123,7 @@ def test_inline_metadata_add_4():
|
||||
assert inline.dict["added_key"] == ["added_value"]
|
||||
|
||||
|
||||
def test_inline_metadata_add_5():
|
||||
def test_add_5():
|
||||
"""Test InlineMetadata add() method.
|
||||
|
||||
GIVEN a InlineMetadata object
|
||||
@@ -135,7 +135,7 @@ def test_inline_metadata_add_5():
|
||||
assert inline.dict["key1"] == ["value1", "value2", "value3", "new_value"]
|
||||
|
||||
|
||||
def test_inline_metadata_add_6():
|
||||
def test_add_6():
|
||||
"""Test InlineMetadata add() method.
|
||||
|
||||
GIVEN a InlineMetadata object
|
||||
@@ -147,7 +147,7 @@ def test_inline_metadata_add_6():
|
||||
assert inline.dict["key2"] == ["new_value", "new_value2", "value1"]
|
||||
|
||||
|
||||
def test_inline_metadata_add_7():
|
||||
def test_add_7():
|
||||
"""Test InlineMetadata add() method.
|
||||
|
||||
GIVEN a InlineMetadata object
|
||||
@@ -159,7 +159,19 @@ def test_inline_metadata_add_7():
|
||||
assert inline.dict["key1"] == ["new_value", "new_value2", "value1", "value2", "value3"]
|
||||
|
||||
|
||||
def test_inline_metadata_contains_1():
|
||||
def test_add_8():
|
||||
"""Test InlineMetadata add() method.
|
||||
|
||||
GIVEN a InlineMetadata object
|
||||
WHEN the add() method is called with a new key and a list of values
|
||||
THEN return True and add the new values to the dict
|
||||
"""
|
||||
inline = InlineMetadata(INLINE_CONTENT)
|
||||
assert inline.add("new_key", ["value1", "new_value", "new_value2"]) is True
|
||||
assert inline.dict["new_key"] == ["value1", "new_value", "new_value2"]
|
||||
|
||||
|
||||
def test_contains_1():
|
||||
"""Test InlineMetadata contains() method.
|
||||
|
||||
GIVEN a InlineMetadata object
|
||||
@@ -170,7 +182,7 @@ def test_inline_metadata_contains_1():
|
||||
assert inline.contains("key1") is True
|
||||
|
||||
|
||||
def test_inline_metadata_contains_2():
|
||||
def test_contains_2():
|
||||
"""Test InlineMetadata contains() method.
|
||||
|
||||
GIVEN a InlineMetadata object
|
||||
@@ -181,7 +193,7 @@ def test_inline_metadata_contains_2():
|
||||
assert inline.contains("no_key") is False
|
||||
|
||||
|
||||
def test_inline_metadata_contains_3():
|
||||
def test_contains_3():
|
||||
"""Test InlineMetadata contains() method.
|
||||
|
||||
GIVEN a InlineMetadata object
|
||||
@@ -192,7 +204,7 @@ def test_inline_metadata_contains_3():
|
||||
assert inline.contains("key1", "value1") is True
|
||||
|
||||
|
||||
def test_inline_metadata_contains_4():
|
||||
def test_contains_4():
|
||||
"""Test InlineMetadata contains() method.
|
||||
|
||||
GIVEN a InlineMetadata object
|
||||
@@ -203,7 +215,7 @@ def test_inline_metadata_contains_4():
|
||||
assert inline.contains("key1", "no value") is False
|
||||
|
||||
|
||||
def test_inline_metadata_contains_5():
|
||||
def test_contains_5():
|
||||
"""Test InlineMetadata contains() method.
|
||||
|
||||
GIVEN a InlineMetadata object
|
||||
@@ -214,7 +226,7 @@ def test_inline_metadata_contains_5():
|
||||
assert inline.contains(r"\d$", is_regex=True) is True
|
||||
|
||||
|
||||
def test_inline_metadata_contains_6():
|
||||
def test_contains_6():
|
||||
"""Test InlineMetadata contains() method.
|
||||
|
||||
GIVEN a InlineMetadata object
|
||||
@@ -225,7 +237,7 @@ def test_inline_metadata_contains_6():
|
||||
assert inline.contains(r"^\d", is_regex=True) is False
|
||||
|
||||
|
||||
def test_inline_metadata_contains_7():
|
||||
def test_contains_7():
|
||||
"""Test InlineMetadata contains() method.
|
||||
|
||||
GIVEN a InlineMetadata object
|
||||
@@ -236,7 +248,7 @@ def test_inline_metadata_contains_7():
|
||||
assert inline.contains(r"key\d", r"\w\d", is_regex=True) is True
|
||||
|
||||
|
||||
def test_inline_metadata_contains_8():
|
||||
def test_contains_8():
|
||||
"""Test InlineMetadata contains() method.
|
||||
|
||||
GIVEN a InlineMetadata object
|
||||
@@ -247,7 +259,7 @@ def test_inline_metadata_contains_8():
|
||||
assert inline.contains("key1", r"_\d", is_regex=True) is False
|
||||
|
||||
|
||||
def test_inline_metadata_delete_1():
|
||||
def test_delete_1():
|
||||
"""Test InlineMetadata delete() method.
|
||||
|
||||
GIVEN a InlineMetadata object
|
||||
@@ -258,7 +270,7 @@ def test_inline_metadata_delete_1():
|
||||
assert inline.delete("no key") is False
|
||||
|
||||
|
||||
def test_inline_metadata_delete_2():
|
||||
def test_delete_2():
|
||||
"""Test InlineMetadata delete() method.
|
||||
|
||||
GIVEN a InlineMetadata object
|
||||
@@ -269,7 +281,7 @@ def test_inline_metadata_delete_2():
|
||||
assert inline.delete("key1", "no value") is False
|
||||
|
||||
|
||||
def test_inline_metadata_delete_3():
|
||||
def test_delete_3():
|
||||
"""Test InlineMetadata delete() method.
|
||||
|
||||
GIVEN a InlineMetadata object
|
||||
@@ -280,7 +292,7 @@ def test_inline_metadata_delete_3():
|
||||
assert inline.delete(r"\d{3}") is False
|
||||
|
||||
|
||||
def test_inline_metadata_delete_4():
|
||||
def test_delete_4():
|
||||
"""Test InlineMetadata delete() method.
|
||||
|
||||
GIVEN a InlineMetadata object
|
||||
@@ -291,7 +303,7 @@ def test_inline_metadata_delete_4():
|
||||
assert inline.delete("key1", r"\d{5}") is False
|
||||
|
||||
|
||||
def test_inline_metadata_delete_5():
|
||||
def test_delete_5():
|
||||
"""Test InlineMetadata delete() method.
|
||||
|
||||
GIVEN a InlineMetadata object
|
||||
@@ -304,7 +316,7 @@ def test_inline_metadata_delete_5():
|
||||
assert "key1" in inline.dict
|
||||
|
||||
|
||||
def test_inline_metadata_delete_6():
|
||||
def test_delete_6():
|
||||
"""Test InlineMetadata delete() method.
|
||||
|
||||
GIVEN a InlineMetadata object
|
||||
@@ -316,7 +328,7 @@ def test_inline_metadata_delete_6():
|
||||
assert "key1" not in inline.dict
|
||||
|
||||
|
||||
def test_inline_metadata_delete_7():
|
||||
def test_delete_7():
|
||||
"""Test InlineMetadata delete() method.
|
||||
|
||||
GIVEN a InlineMetadata object
|
||||
@@ -329,7 +341,7 @@ def test_inline_metadata_delete_7():
|
||||
assert "key2" not in inline.dict
|
||||
|
||||
|
||||
def test_inline_metadata_delete_8():
|
||||
def test_delete_8():
|
||||
"""Test InlineMetadata delete() method.
|
||||
|
||||
GIVEN a InlineMetadata object
|
||||
@@ -343,7 +355,7 @@ def test_inline_metadata_delete_8():
|
||||
assert "value3" not in inline.dict["key1"]
|
||||
|
||||
|
||||
def test_inline_metadata_has_changes_1():
|
||||
def test_has_changes_1():
|
||||
"""Test InlineMetadata has_changes() method.
|
||||
|
||||
GIVEN a InlineMetadata object
|
||||
@@ -354,7 +366,7 @@ def test_inline_metadata_has_changes_1():
|
||||
assert inline.has_changes() is False
|
||||
|
||||
|
||||
def test_inline_metadata_has_changes_2():
|
||||
def test_has_changes_2():
|
||||
"""Test InlineMetadata has_changes() method.
|
||||
|
||||
GIVEN a InlineMetadata object
|
||||
@@ -366,7 +378,7 @@ def test_inline_metadata_has_changes_2():
|
||||
assert inline.has_changes() is True
|
||||
|
||||
|
||||
def test_inline_metadata_rename_1():
|
||||
def test_rename_1():
|
||||
"""Test InlineMetadata rename() method.
|
||||
|
||||
GIVEN a InlineMetadata object
|
||||
@@ -377,7 +389,7 @@ def test_inline_metadata_rename_1():
|
||||
assert inline.rename("no key", "new key") is False
|
||||
|
||||
|
||||
def test_inline_metadata_rename_2():
|
||||
def test_rename_2():
|
||||
"""Test InlineMetadata rename() method.
|
||||
|
||||
GIVEN a InlineMetadata object
|
||||
@@ -388,7 +400,7 @@ def test_inline_metadata_rename_2():
|
||||
assert inline.rename("key1", "no value", "new value") is False
|
||||
|
||||
|
||||
def test_inline_metadata_rename_3():
|
||||
def test_rename_3():
|
||||
"""Test InlineMetadata rename() method.
|
||||
|
||||
GIVEN a InlineMetadata object
|
||||
@@ -401,7 +413,7 @@ def test_inline_metadata_rename_3():
|
||||
assert inline.dict["new key"] == ["value1", "value2", "value3"]
|
||||
|
||||
|
||||
def test_inline_metadata_rename_4():
|
||||
def test_rename_4():
|
||||
"""Test InlineMetadata rename() method.
|
||||
|
||||
GIVEN a InlineMetadata object
|
||||
@@ -414,7 +426,7 @@ def test_inline_metadata_rename_4():
|
||||
assert "new value" in inline.dict["key1"]
|
||||
|
||||
|
||||
def test_inline_metadata_rename_5():
|
||||
def test_rename_5():
|
||||
"""Test InlineMetadata rename() method.
|
||||
|
||||
GIVEN a InlineMetadata object
|
||||
|
||||
367
tests/metadata_tags_test.py
Normal file
367
tests/metadata_tags_test.py
Normal file
@@ -0,0 +1,367 @@
|
||||
# type: ignore
|
||||
"""Test inline tags from metadata.py."""
|
||||
|
||||
from obsidian_metadata.models.metadata import InlineTags
|
||||
|
||||
CONTENT = """\
|
||||
#tag1 #tag2
|
||||
> #tag3
|
||||
**#tag4**
|
||||
I am a sentence with #tag5 and #tag6 in the middle
|
||||
#tag🙈7
|
||||
#tag/8
|
||||
#tag/👋/9
|
||||
"""
|
||||
|
||||
|
||||
def test__grab_inline_tags_1() -> None:
|
||||
"""Test _grab_inline_tags() method.
|
||||
|
||||
GIVEN a string with a codeblock
|
||||
WHEN the method is called
|
||||
THEN the codeblock is ignored
|
||||
"""
|
||||
content = """
|
||||
some text
|
||||
|
||||
```python
|
||||
#tag1
|
||||
#tag2
|
||||
```
|
||||
|
||||
```
|
||||
#tag3
|
||||
#tag4
|
||||
```
|
||||
"""
|
||||
tags = InlineTags(content)
|
||||
assert tags.list == []
|
||||
assert tags.list_original == []
|
||||
|
||||
|
||||
def test__grab_inline_tags_2() -> None:
|
||||
"""Test _grab_inline_tags() method.
|
||||
|
||||
GIVEN a string with tags
|
||||
WHEN the method is called
|
||||
THEN the tags are extracted
|
||||
"""
|
||||
tags = InlineTags(CONTENT)
|
||||
assert tags.list == [
|
||||
"tag/8",
|
||||
"tag/👋/9",
|
||||
"tag1",
|
||||
"tag2",
|
||||
"tag3",
|
||||
"tag4",
|
||||
"tag5",
|
||||
"tag6",
|
||||
"tag🙈7",
|
||||
]
|
||||
assert tags.list_original == [
|
||||
"tag/8",
|
||||
"tag/👋/9",
|
||||
"tag1",
|
||||
"tag2",
|
||||
"tag3",
|
||||
"tag4",
|
||||
"tag5",
|
||||
"tag6",
|
||||
"tag🙈7",
|
||||
]
|
||||
|
||||
|
||||
def test_add_1():
|
||||
"""Test add() method.
|
||||
|
||||
GIVEN a InlineTag object
|
||||
WHEN the add() method is called with a tag that exists in the list
|
||||
THEN return False
|
||||
"""
|
||||
tags = InlineTags(CONTENT)
|
||||
assert tags.add("tag1") is False
|
||||
|
||||
|
||||
def test_add_2():
|
||||
"""Test add() method.
|
||||
|
||||
GIVEN a InlineTag object
|
||||
WHEN the add() method is called with a new tag
|
||||
THEN return True and add the tag to the list
|
||||
"""
|
||||
tags = InlineTags(CONTENT)
|
||||
assert tags.add("new_tag") is True
|
||||
assert "new_tag" in tags.list
|
||||
|
||||
|
||||
def test_add_3():
|
||||
"""Test add() method.
|
||||
|
||||
GIVEN a InlineTag object
|
||||
WHEN the add() method is called with a list of new tags
|
||||
THEN return True and add the tags to the list
|
||||
"""
|
||||
tags = InlineTags(CONTENT)
|
||||
new_tags = ["new_tag1", "new_tag2"]
|
||||
assert tags.add(new_tags) is True
|
||||
assert "new_tag1" in tags.list
|
||||
assert "new_tag2" in tags.list
|
||||
|
||||
|
||||
def test_add_4():
|
||||
"""Test add() method.
|
||||
|
||||
GIVEN a InlineTag object
|
||||
WHEN the add() method is called with a list of tags, some of which already exist
|
||||
THEN return True and add only the new tags to the list
|
||||
"""
|
||||
tags = InlineTags(CONTENT)
|
||||
new_tags = ["new_tag1", "new_tag2", "tag1", "tag2"]
|
||||
assert tags.add(new_tags) is True
|
||||
assert tags.list == [
|
||||
"new_tag1",
|
||||
"new_tag2",
|
||||
"tag/8",
|
||||
"tag/👋/9",
|
||||
"tag1",
|
||||
"tag2",
|
||||
"tag3",
|
||||
"tag4",
|
||||
"tag5",
|
||||
"tag6",
|
||||
"tag🙈7",
|
||||
]
|
||||
|
||||
|
||||
def test_add_5():
|
||||
"""Test add() method.
|
||||
|
||||
GIVEN a InlineTag object
|
||||
WHEN the add() method is called with a list of tags which are already in the list
|
||||
THEN return False
|
||||
"""
|
||||
tags = InlineTags(CONTENT)
|
||||
new_tags = ["tag1", "tag2"]
|
||||
assert tags.add(new_tags) is False
|
||||
assert "tag1" in tags.list
|
||||
assert "tag2" in tags.list
|
||||
|
||||
|
||||
def test_add_6():
|
||||
"""Test add() method.
|
||||
|
||||
GIVEN a InlineTag object
|
||||
WHEN the add() method is called with a list of tags which have a # in the name
|
||||
THEN strip the # from the tag name
|
||||
"""
|
||||
tags = InlineTags(CONTENT)
|
||||
new_tags = ["#tag1", "#tag2", "#new_tag"]
|
||||
assert tags.add(new_tags) is True
|
||||
assert tags.list == [
|
||||
"new_tag",
|
||||
"tag/8",
|
||||
"tag/👋/9",
|
||||
"tag1",
|
||||
"tag2",
|
||||
"tag3",
|
||||
"tag4",
|
||||
"tag5",
|
||||
"tag6",
|
||||
"tag🙈7",
|
||||
]
|
||||
|
||||
|
||||
def test_add_7():
|
||||
"""Test add() method.
|
||||
|
||||
GIVEN a InlineTag object
|
||||
WHEN the add() method is called with a tag which has a # in the name
|
||||
THEN strip the # from the tag name
|
||||
"""
|
||||
tags = InlineTags(CONTENT)
|
||||
assert tags.add("#tag1") is False
|
||||
assert tags.add("#new_tag") is True
|
||||
assert "new_tag" in tags.list
|
||||
|
||||
|
||||
def test_contains_1():
|
||||
"""Test contains() method.
|
||||
|
||||
GIVEN a InlineTag object
|
||||
WHEN the contains() method is called with a tag that exists in the list
|
||||
THEN return True
|
||||
"""
|
||||
tags = InlineTags(CONTENT)
|
||||
assert tags.contains("tag1") is True
|
||||
|
||||
|
||||
def test_contains_2():
|
||||
"""Test contains() method.
|
||||
|
||||
GIVEN a InlineTag object
|
||||
WHEN the contains() method is called with a tag that does not exist in the list
|
||||
THEN return False
|
||||
"""
|
||||
tags = InlineTags(CONTENT)
|
||||
assert tags.contains("no_tag") is False
|
||||
|
||||
|
||||
def test_contains_3():
|
||||
"""Test contains() method.
|
||||
|
||||
GIVEN a InlineTag object
|
||||
WHEN the contains() method is called with a regex that matches a tag in the list
|
||||
THEN return True
|
||||
"""
|
||||
tags = InlineTags(CONTENT)
|
||||
assert tags.contains(r"tag\d", is_regex=True) is True
|
||||
|
||||
|
||||
def test_contains_4():
|
||||
"""Test contains() method.
|
||||
|
||||
GIVEN a InlineTag object
|
||||
WHEN the contains() method is called with a regex that does not match any tags in the list
|
||||
THEN return False
|
||||
"""
|
||||
tags = InlineTags(CONTENT)
|
||||
assert tags.contains(r"tag\d\d", is_regex=True) is False
|
||||
|
||||
|
||||
def test_delete_1():
|
||||
"""Test delete() method.
|
||||
|
||||
GIVEN a InlineTag object
|
||||
WHEN the delete() method is called with a tag that exists in the list
|
||||
THEN return True and remove the tag from the list
|
||||
"""
|
||||
tags = InlineTags(CONTENT)
|
||||
assert tags.delete("tag1") is True
|
||||
assert "tag1" not in tags.list
|
||||
|
||||
|
||||
def test_delete_2():
|
||||
"""Test delete() method.
|
||||
|
||||
GIVEN a InlineTag object
|
||||
WHEN the delete() method is called with a tag that does not exist in the list
|
||||
THEN return False
|
||||
"""
|
||||
tags = InlineTags(CONTENT)
|
||||
assert tags.delete("no_tag") is False
|
||||
|
||||
|
||||
def test_delete_3():
|
||||
"""Test delete() method.
|
||||
|
||||
GIVEN a InlineTag object
|
||||
WHEN the delete() method is called with a regex that matches a tag in the list
|
||||
THEN return True and remove the tag from the list
|
||||
"""
|
||||
tags = InlineTags(CONTENT)
|
||||
assert tags.delete(r"tag\d") is True
|
||||
assert tags.list == ["tag/8", "tag/👋/9", "tag🙈7"]
|
||||
|
||||
|
||||
def test_delete_4():
|
||||
"""Test delete() method.
|
||||
|
||||
GIVEN a InlineTag object
|
||||
WHEN the delete() method is called with a regex that does not match any tags in the list
|
||||
THEN return False
|
||||
"""
|
||||
tags = InlineTags(CONTENT)
|
||||
assert tags.delete(r"tag\d\d") is False
|
||||
|
||||
|
||||
def test_has_changes_1():
|
||||
"""Test has_changes() method.
|
||||
|
||||
GIVEN a InlineTag object
|
||||
WHEN the has_changes() method is called
|
||||
THEN return False
|
||||
"""
|
||||
tags = InlineTags(CONTENT)
|
||||
assert tags.has_changes() is False
|
||||
|
||||
|
||||
def test_has_changes_2():
|
||||
"""Test has_changes() method.
|
||||
|
||||
GIVEN a InlineTag object
|
||||
WHEN the has_changes() method after the list has been updated
|
||||
THEN return True
|
||||
"""
|
||||
tags = InlineTags(CONTENT)
|
||||
tags.list = ["new_tag"]
|
||||
assert tags.has_changes() is True
|
||||
|
||||
|
||||
def test_rename_1():
|
||||
"""Test rename() method.
|
||||
|
||||
GIVEN a InlineTag object
|
||||
WHEN the rename() method is called with a tag that exists in the list
|
||||
THEN return True and rename the tag in the list
|
||||
"""
|
||||
tags = InlineTags(CONTENT)
|
||||
assert tags.rename("tag1", "new_tag") is True
|
||||
assert "tag1" not in tags.list
|
||||
assert "new_tag" in tags.list
|
||||
|
||||
|
||||
def test_rename_2():
|
||||
"""Test rename() method.
|
||||
|
||||
GIVEN a InlineTag object
|
||||
WHEN the rename() method is called with a tag that does not exist in the list
|
||||
THEN return False
|
||||
"""
|
||||
tags = InlineTags(CONTENT)
|
||||
assert tags.rename("no_tag", "new_tag") is False
|
||||
assert "new_tag" not in tags.list
|
||||
|
||||
|
||||
def test_rename_3():
|
||||
"""Test rename() method.
|
||||
|
||||
GIVEN a InlineTag object
|
||||
WHEN the rename() method is called with a tag that exists and the new tag name already exists in the list
|
||||
THEN return True and ensure the new tag name is only in the list once
|
||||
"""
|
||||
tags = InlineTags(CONTENT)
|
||||
assert tags.rename(r"tag1", "tag2") is True
|
||||
assert tags.list == [
|
||||
"tag/8",
|
||||
"tag/👋/9",
|
||||
"tag2",
|
||||
"tag3",
|
||||
"tag4",
|
||||
"tag5",
|
||||
"tag6",
|
||||
"tag🙈7",
|
||||
]
|
||||
|
||||
|
||||
def test_rename_4():
|
||||
"""Test rename() method.
|
||||
|
||||
GIVEN a InlineTag object
|
||||
WHEN the rename() method is called with a new tag value that is None
|
||||
THEN return False
|
||||
"""
|
||||
tags = InlineTags(CONTENT)
|
||||
assert tags.rename("tag1", None) is False
|
||||
assert "tag1" in tags.list
|
||||
|
||||
|
||||
def test_rename_5():
|
||||
"""Test rename() method.
|
||||
|
||||
GIVEN a InlineTag object
|
||||
WHEN the rename() method is called with a new tag value that is empty
|
||||
THEN return False
|
||||
"""
|
||||
tags = InlineTags(CONTENT)
|
||||
assert tags.rename("tag1", "") is False
|
||||
assert "tag1" in tags.list
|
||||
@@ -1,393 +0,0 @@
|
||||
# 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
|
||||
814
tests/metadata_vault_test.py
Normal file
814
tests/metadata_vault_test.py
Normal file
@@ -0,0 +1,814 @@
|
||||
# type: ignore
|
||||
"""Test VaultMetadata object from metadata.py."""
|
||||
import pytest
|
||||
|
||||
from obsidian_metadata.models.enums import MetadataType
|
||||
from obsidian_metadata.models.metadata import (
|
||||
VaultMetadata,
|
||||
)
|
||||
from tests.helpers import Regex, remove_ansi
|
||||
|
||||
|
||||
def test_vault_metadata__init_1() -> None:
|
||||
"""Test VaultMetadata class."""
|
||||
vm = VaultMetadata()
|
||||
assert vm.dict == {}
|
||||
assert vm.frontmatter == {}
|
||||
assert vm.inline_metadata == {}
|
||||
assert vm.tags == []
|
||||
|
||||
|
||||
def test_index_metadata_1():
|
||||
"""Test index_metadata() method.
|
||||
|
||||
GIVEN a dictionary to add
|
||||
WHEN the target area is FRONTMATTER and the old dictionary is empty
|
||||
THEN the new dictionary is added to the target area
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
new_dict = {"key1": ["value1"], "key2": ["value2", "value3"]}
|
||||
vm.index_metadata(area=MetadataType.FRONTMATTER, metadata=new_dict)
|
||||
assert vm.dict == new_dict
|
||||
assert vm.frontmatter == new_dict
|
||||
|
||||
|
||||
def test_index_metadata_2():
|
||||
"""Test index_metadata() method.
|
||||
|
||||
GIVEN a dictionary to add
|
||||
WHEN the target area is FRONTMATTER and the old dictionary is not empty
|
||||
THEN the new dictionary is merged with the old dictionary
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.dict = {"key1": ["value1"], "key2": ["value1", "value2"], "other_key": ["value1"]}
|
||||
vm.frontmatter = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
|
||||
new_dict = {"key1": ["value1"], "key2": ["value1", "value3"], "key3": ["value1"]}
|
||||
|
||||
vm.index_metadata(area=MetadataType.FRONTMATTER, metadata=new_dict)
|
||||
assert vm.dict == {
|
||||
"key1": ["value1"],
|
||||
"key2": ["value1", "value2", "value3"],
|
||||
"key3": ["value1"],
|
||||
"other_key": ["value1"],
|
||||
}
|
||||
assert vm.frontmatter == {
|
||||
"key1": ["value1"],
|
||||
"key2": ["value1", "value2", "value3"],
|
||||
"key3": ["value1"],
|
||||
}
|
||||
|
||||
|
||||
def test_index_metadata_3():
|
||||
"""Test index_metadata() method.
|
||||
|
||||
GIVEN a dictionary to add
|
||||
WHEN the target area is INLINE and the old dictionary is empty
|
||||
THEN the new dictionary is added to the target area
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
new_dict = {"key1": ["value1"], "key2": ["value2", "value3"]}
|
||||
vm.index_metadata(area=MetadataType.INLINE, metadata=new_dict)
|
||||
assert vm.dict == new_dict
|
||||
assert vm.inline_metadata == new_dict
|
||||
|
||||
|
||||
def test_index_metadata_4():
|
||||
"""Test index_metadata() method.
|
||||
|
||||
GIVEN a dictionary to add
|
||||
WHEN the target area is INLINE and the old dictionary is not empty
|
||||
THEN the new dictionary is merged with the old dictionary
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.dict = {"key1": ["value1"], "key2": ["value1", "value2"], "other_key": ["value1"]}
|
||||
vm.inline_metadata = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
|
||||
new_dict = {"key1": ["value1"], "key2": ["value1", "value3"], "key3": ["value1"]}
|
||||
|
||||
vm.index_metadata(area=MetadataType.INLINE, metadata=new_dict)
|
||||
assert vm.dict == {
|
||||
"key1": ["value1"],
|
||||
"key2": ["value1", "value2", "value3"],
|
||||
"key3": ["value1"],
|
||||
"other_key": ["value1"],
|
||||
}
|
||||
assert vm.inline_metadata == {
|
||||
"key1": ["value1"],
|
||||
"key2": ["value1", "value2", "value3"],
|
||||
"key3": ["value1"],
|
||||
}
|
||||
|
||||
|
||||
def test_index_metadata_5():
|
||||
"""Test index_metadata() method.
|
||||
|
||||
GIVEN a dictionary to add
|
||||
WHEN the target area is TAGS and the old list is empty
|
||||
THEN the new list is added to the target area
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
new_list = ["tag1", "tag2", "tag3"]
|
||||
vm.index_metadata(area=MetadataType.TAGS, metadata=new_list)
|
||||
assert vm.dict == {}
|
||||
assert vm.tags == new_list
|
||||
|
||||
|
||||
def test_index_metadata_6():
|
||||
"""Test index_metadata() method.
|
||||
|
||||
GIVEN a dictionary to add
|
||||
WHEN the target area is TAGS and the old list is not empty
|
||||
THEN the new list is merged with the old list
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.tags = ["tag1", "tag2", "tag3"]
|
||||
new_list = ["tag1", "tag2", "tag4", "tag5"]
|
||||
|
||||
vm.index_metadata(area=MetadataType.TAGS, metadata=new_list)
|
||||
assert vm.dict == {}
|
||||
assert vm.tags == ["tag1", "tag2", "tag3", "tag4", "tag5"]
|
||||
|
||||
|
||||
def test_contains_1():
|
||||
"""Test contains() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN FRONTMATTER is checked for a key that exists
|
||||
THEN True is returned
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.frontmatter = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
assert vm.contains(area=MetadataType.FRONTMATTER, key="key1") is True
|
||||
|
||||
|
||||
def test_contains_2():
|
||||
"""Test contains() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN FRONTMATTER is checked for a key that does not exist
|
||||
THEN False is returned
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.frontmatter = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
assert vm.contains(area=MetadataType.FRONTMATTER, key="key3") is False
|
||||
|
||||
|
||||
def test_contains_3():
|
||||
"""Test contains() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN FRONTMATTER is checked for a key and value that exists
|
||||
THEN True is returned
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.frontmatter = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
assert vm.contains(area=MetadataType.FRONTMATTER, key="key2", value="value1") is True
|
||||
|
||||
|
||||
def test_contains_4():
|
||||
"""Test contains() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN FRONTMATTER is checked for a key and value that does not exist
|
||||
THEN False is returned
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.frontmatter = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
assert vm.contains(area=MetadataType.FRONTMATTER, key="key2", value="value3") is False
|
||||
|
||||
|
||||
def test_contains_5():
|
||||
"""Test contains() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN FRONTMATTER is checked for a key that exists with regex
|
||||
THEN True is returned
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.frontmatter = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
assert vm.contains(area=MetadataType.FRONTMATTER, key=r"\w+\d", is_regex=True) is True
|
||||
|
||||
|
||||
def test_contains_6():
|
||||
"""Test contains() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN FRONTMATTER is checked for a key that does not exist with regex
|
||||
THEN False is returned
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.frontmatter = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
assert vm.contains(area=MetadataType.FRONTMATTER, key=r"^\d", is_regex=True) is False
|
||||
|
||||
|
||||
def test_contains_7():
|
||||
"""Test contains() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN FRONTMATTER is checked for a key and value that exists with regex
|
||||
THEN True is returned
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.frontmatter = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
assert (
|
||||
vm.contains(area=MetadataType.FRONTMATTER, key="key2", value=r"\w\d", is_regex=True) is True
|
||||
)
|
||||
|
||||
|
||||
def test_contains_8():
|
||||
"""Test contains() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN FRONTMATTER is checked for a key and value that does not exist with regex
|
||||
THEN False is returned
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.frontmatter = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
assert (
|
||||
vm.contains(area=MetadataType.FRONTMATTER, key="key2", value=r"^\d", is_regex=True) is False
|
||||
)
|
||||
|
||||
|
||||
def test_contains_9():
|
||||
"""Test contains() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN FRONTMATTER is checked with a key is None
|
||||
THEN raise a ValueError
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.frontmatter = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
with pytest.raises(ValueError, match="Key must be provided"):
|
||||
vm.contains(area=MetadataType.FRONTMATTER, value="value1")
|
||||
|
||||
|
||||
def test_contains_10():
|
||||
"""Test contains() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN INLINE is checked for a key that exists
|
||||
THEN True is returned
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.inline_metadata = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
assert vm.contains(area=MetadataType.INLINE, key="key1") is True
|
||||
|
||||
|
||||
def test_contains_11():
|
||||
"""Test contains() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN INLINE is checked for a key that does not exist
|
||||
THEN False is returned
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.inline_metadata = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
assert vm.contains(area=MetadataType.INLINE, key="key3") is False
|
||||
|
||||
|
||||
def test_contains_12():
|
||||
"""Test contains() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN INLINE is checked for a key and value that exists
|
||||
THEN True is returned
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.inline_metadata = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
assert vm.contains(area=MetadataType.INLINE, key="key2", value="value1") is True
|
||||
|
||||
|
||||
def test_contains_13():
|
||||
"""Test contains() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN INLINE is checked for a key and value that does not exist
|
||||
THEN False is returned
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.inline_metadata = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
assert vm.contains(area=MetadataType.INLINE, key="key2", value="value3") is False
|
||||
|
||||
|
||||
def test_contains_14():
|
||||
"""Test contains() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN INLINE is checked for a key that exists with regex
|
||||
THEN True is returned
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.inline_metadata = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
assert vm.contains(area=MetadataType.INLINE, key=r"\w+\d", is_regex=True) is True
|
||||
|
||||
|
||||
def test_contains_15():
|
||||
"""Test contains() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN INLINE is checked for a key that does not exist with regex
|
||||
THEN False is returned
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.inline_metadata = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
assert vm.contains(area=MetadataType.INLINE, key=r"^\d", is_regex=True) is False
|
||||
|
||||
|
||||
def test_contains_16():
|
||||
"""Test contains() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN INLINE is checked for a key and value that exists with regex
|
||||
THEN True is returned
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.inline_metadata = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
assert vm.contains(area=MetadataType.INLINE, key="key2", value=r"\w\d", is_regex=True) is True
|
||||
|
||||
|
||||
def test_contains_17():
|
||||
"""Test contains() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN INLINE is checked for a key and value that does not exist with regex
|
||||
THEN False is returned
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.inline_metadata = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
assert vm.contains(area=MetadataType.INLINE, key="key2", value=r"^\d", is_regex=True) is False
|
||||
|
||||
|
||||
def test_contains_18():
|
||||
"""Test contains() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN INLINE is checked with a key is None
|
||||
THEN raise a ValueError
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.inline_metadata = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
with pytest.raises(ValueError, match="Key must be provided"):
|
||||
vm.contains(area=MetadataType.INLINE, value="value1")
|
||||
|
||||
|
||||
def test_contains_19():
|
||||
"""Test contains() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN TAGS is checked for a key but not a value
|
||||
THEN raise a ValueError
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.tags = ["tag1", "tag2", "tag3"]
|
||||
with pytest.raises(ValueError, match="Value must be provided"):
|
||||
vm.contains(area=MetadataType.TAGS, key="key1")
|
||||
|
||||
|
||||
def test_contains_20():
|
||||
"""Test contains() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN TAGS is checked for a value that exists
|
||||
THEN True is returned
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.tags = ["tag1", "tag2", "tag3"]
|
||||
assert vm.contains(area=MetadataType.TAGS, value="tag1") is True
|
||||
|
||||
|
||||
def test_contains_21():
|
||||
"""Test contains() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN TAGS is checked for a value that does not exist
|
||||
THEN False is returned
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.tags = ["tag1", "tag2", "tag3"]
|
||||
assert vm.contains(area=MetadataType.TAGS, value="value1") is False
|
||||
|
||||
|
||||
def test_contains_22():
|
||||
"""Test contains() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN TAGS is checked for a key regex but no value
|
||||
THEN True is returned
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.tags = ["tag1", "tag2", "tag3"]
|
||||
with pytest.raises(ValueError, match="Value must be provided"):
|
||||
vm.contains(area=MetadataType.TAGS, key=r"\w", is_regex=True)
|
||||
|
||||
|
||||
def test_contains_23():
|
||||
"""Test contains() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN TAGS is checked for a value that does not exist with regex
|
||||
THEN False is returned
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.tags = ["tag1", "tag2", "tag3"]
|
||||
assert vm.contains(area=MetadataType.TAGS, value=r"^\d", is_regex=True) is False
|
||||
|
||||
|
||||
def test_contains_24():
|
||||
"""Test contains() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN TAGS is checked for a value that exists with regex
|
||||
THEN True is returned
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.tags = ["tag1", "tag2", "tag3"]
|
||||
assert vm.contains(area=MetadataType.TAGS, value=r"^tag\d", is_regex=True) is True
|
||||
|
||||
|
||||
def test_contains_25():
|
||||
"""Test contains() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN ALL is checked for a key that exists
|
||||
THEN True is returned
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.dict = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
assert vm.contains(area=MetadataType.ALL, key="key1") is True
|
||||
|
||||
|
||||
def test_contains_26():
|
||||
"""Test contains() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN ALL is checked for a key that does not exist
|
||||
THEN False is returned
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.dict = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
assert vm.contains(area=MetadataType.ALL, key="key3") is False
|
||||
|
||||
|
||||
def test_contains_27():
|
||||
"""Test contains() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN ALL is checked for a key and value that exists
|
||||
THEN True is returned
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.dict = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
assert vm.contains(area=MetadataType.ALL, key="key2", value="value1") is True
|
||||
|
||||
|
||||
def test_contains_28():
|
||||
"""Test contains() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN ALL is checked for a key and value that does not exist
|
||||
THEN False is returned
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.dict = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
assert vm.contains(area=MetadataType.ALL, key="key2", value="value3") is False
|
||||
|
||||
|
||||
def test_contains_29():
|
||||
"""Test contains() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN ALL is checked for a key that exists with regex
|
||||
THEN True is returned
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.dict = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
assert vm.contains(area=MetadataType.ALL, key=r"\w+\d", is_regex=True) is True
|
||||
|
||||
|
||||
def test_contains_30():
|
||||
"""Test contains() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN ALL is checked for a key that does not exist with regex
|
||||
THEN False is returned
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.dict = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
assert vm.contains(area=MetadataType.ALL, key=r"^\d", is_regex=True) is False
|
||||
|
||||
|
||||
def test_contains_31():
|
||||
"""Test contains() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN ALL is checked for a key and value that exists with regex
|
||||
THEN True is returned
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.dict = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
assert vm.contains(area=MetadataType.ALL, key="key2", value=r"\w\d", is_regex=True) is True
|
||||
|
||||
|
||||
def test_contains_32():
|
||||
"""Test contains() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN ALL is checked for a key and value that does not exist with regex
|
||||
THEN False is returned
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.dict = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
assert vm.contains(area=MetadataType.ALL, key="key2", value=r"^\d", is_regex=True) is False
|
||||
|
||||
|
||||
def test_contains_33():
|
||||
"""Test contains() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN ALL is checked with a key is None
|
||||
THEN raise a ValueError
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.dict = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
with pytest.raises(ValueError, match="Key must be provided"):
|
||||
vm.contains(area=MetadataType.ALL, value="value1")
|
||||
|
||||
|
||||
def test_delete_1():
|
||||
"""Test delete() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN a key is deleted
|
||||
THEN return True and the key is removed
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.dict = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
assert vm.delete(key="key1") is True
|
||||
assert vm.dict == {"key2": ["value1", "value2"]}
|
||||
|
||||
|
||||
def test_delete_2():
|
||||
"""Test delete() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN a key is deleted that does not exist
|
||||
THEN return False and the key is not removed
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.dict = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
assert vm.delete(key="key3") is False
|
||||
assert vm.dict == {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
|
||||
|
||||
def test_delete_3():
|
||||
"""Test delete() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN a key and value are specified
|
||||
THEN return True and remove the value
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.dict = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
assert vm.delete(key="key2", value_to_delete="value1") is True
|
||||
assert vm.dict == {"key1": ["value1"], "key2": ["value2"]}
|
||||
|
||||
|
||||
def test_delete_4():
|
||||
"""Test delete() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN a key and nonexistent value are specified
|
||||
THEN return False
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.dict = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
assert vm.delete(key="key2", value_to_delete="value11") is False
|
||||
assert vm.dict == {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
|
||||
|
||||
def test_rename_1():
|
||||
"""Test VaultMetadata rename() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN the rename() method is called with a key
|
||||
THEN return False if the key is not found
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.dict = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
assert vm.rename("no key", "new key") is False
|
||||
|
||||
|
||||
def test_rename_2():
|
||||
"""Test VaultMetadata rename() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN the rename() method is called with an existing key and non-existing value
|
||||
THEN return False
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.dict = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
assert vm.rename("key1", "no value", "new value") is False
|
||||
|
||||
|
||||
def test_rename_3():
|
||||
"""Test VaultMetadata rename() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN the rename() method is called with an existing key
|
||||
THEN return True and rename the key
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.dict = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
assert vm.rename("key1", "new key") is True
|
||||
assert vm.dict == {"key2": ["value1", "value2"], "new key": ["value1"]}
|
||||
|
||||
|
||||
def test_rename_4():
|
||||
"""Test VaultMetadata rename() method.
|
||||
|
||||
GIVEN a VaultMetadata object
|
||||
WHEN the rename() method is called with an existing key and value
|
||||
THEN return True and rename the value
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.dict = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
assert vm.rename("key1", "value1", "new value") is True
|
||||
assert vm.dict == {"key1": ["new value"], "key2": ["value1", "value2"]}
|
||||
|
||||
|
||||
def test_rename_5():
|
||||
"""Test VaultMetadata rename() method.
|
||||
|
||||
GIVEN a VaultMetadata 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
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.dict = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
assert vm.rename("key2", "value1", "value2") is True
|
||||
assert vm.dict == {"key1": ["value1"], "key2": ["value2"]}
|
||||
|
||||
|
||||
def test_print_metadata_1(capsys):
|
||||
"""Test print_metadata() method.
|
||||
|
||||
GIVEN calling print_metadata() with a VaultMetadata object
|
||||
WHEN ALL is specified
|
||||
THEN print all the metadata
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.dict = {
|
||||
"key1": ["value1", "value2"],
|
||||
"key2": ["value1", "value2"],
|
||||
"key3": ["value1"],
|
||||
"key4": ["value1", "value2"],
|
||||
}
|
||||
vm.frontmatter = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
vm.inline_metadata = {
|
||||
"key1": ["value1", "value2"],
|
||||
"key3": ["value1"],
|
||||
"key4": ["value1", "value2"],
|
||||
}
|
||||
vm.tags = ["tag1", "tag2", "tag3"]
|
||||
|
||||
vm.print_metadata(area=MetadataType.ALL)
|
||||
captured = remove_ansi(capsys.readouterr().out)
|
||||
assert "All metadata" in captured
|
||||
assert captured == Regex("┃ Keys +┃ Values +┃")
|
||||
assert captured == Regex("│ key1 +│ value1 +│")
|
||||
assert captured == Regex("│ key2 +│ value1 +│")
|
||||
assert captured == Regex("│ key4 +│ value1 +│")
|
||||
assert "All inline tags" in captured
|
||||
assert captured == Regex("#tag1 +#tag2")
|
||||
|
||||
|
||||
def test_print_metadata_2(capsys):
|
||||
"""Test print_metadata() method.
|
||||
|
||||
GIVEN calling print_metadata() with a VaultMetadata object
|
||||
WHEN FRONTMATTER is specified
|
||||
THEN print all the metadata
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.dict = {
|
||||
"key1": ["value1", "value2"],
|
||||
"key2": ["value1", "value2"],
|
||||
"key3": ["value1"],
|
||||
"key4": ["value1", "value2"],
|
||||
}
|
||||
vm.frontmatter = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
vm.inline_metadata = {
|
||||
"key1": ["value1", "value2"],
|
||||
"key3": ["value1"],
|
||||
"key4": ["value1", "value2"],
|
||||
}
|
||||
vm.tags = ["tag1", "tag2", "tag3"]
|
||||
|
||||
vm.print_metadata(area=MetadataType.FRONTMATTER)
|
||||
captured = remove_ansi(capsys.readouterr().out)
|
||||
assert "All frontmatter" in captured
|
||||
assert captured == Regex("┃ Keys +┃ Values +┃")
|
||||
assert captured == Regex("│ key1 +│ value1 +│")
|
||||
assert captured == Regex("│ key2 +│ value1 +│")
|
||||
assert captured != Regex("│ key4 +│ value1 +│")
|
||||
assert "All inline tags" not in captured
|
||||
assert captured != Regex("#tag1 +#tag2")
|
||||
|
||||
|
||||
def test_print_metadata_3(capsys):
|
||||
"""Test print_metadata() method.
|
||||
|
||||
GIVEN calling print_metadata() with a VaultMetadata object
|
||||
WHEN INLINE is specified
|
||||
THEN print all the metadata
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.dict = {
|
||||
"key1": ["value1", "value2"],
|
||||
"key2": ["value1", "value2"],
|
||||
"key3": ["value1"],
|
||||
"key4": ["value1", "value2"],
|
||||
}
|
||||
vm.frontmatter = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
vm.inline_metadata = {
|
||||
"key1": ["value1", "value2"],
|
||||
"key3": ["value1"],
|
||||
"key4": ["value1", "value2"],
|
||||
}
|
||||
vm.tags = ["tag1", "tag2", "tag3"]
|
||||
|
||||
vm.print_metadata(area=MetadataType.INLINE)
|
||||
captured = remove_ansi(capsys.readouterr().out)
|
||||
assert "All inline" in captured
|
||||
assert captured == Regex("┃ Keys +┃ Values +┃")
|
||||
assert captured == Regex("│ key1 +│ value1 +│")
|
||||
assert captured != Regex("│ key2 +│ value1 +│")
|
||||
assert captured == Regex("│ key4 +│ value1 +│")
|
||||
assert "All inline tags" not in captured
|
||||
assert captured != Regex("#tag1 +#tag2")
|
||||
|
||||
|
||||
def test_print_metadata_4(capsys):
|
||||
"""Test print_metadata() method.
|
||||
|
||||
GIVEN calling print_metadata() with a VaultMetadata object
|
||||
WHEN TAGS is specified
|
||||
THEN print all the tags
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.dict = {
|
||||
"key1": ["value1", "value2"],
|
||||
"key2": ["value1", "value2"],
|
||||
"key3": ["value1"],
|
||||
"key4": ["value1", "value2"],
|
||||
}
|
||||
vm.frontmatter = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
vm.inline_metadata = {
|
||||
"key1": ["value1", "value2"],
|
||||
"key3": ["value1"],
|
||||
"key4": ["value1", "value2"],
|
||||
}
|
||||
vm.tags = ["tag1", "tag2", "tag3"]
|
||||
|
||||
vm.print_metadata(area=MetadataType.TAGS)
|
||||
captured = remove_ansi(capsys.readouterr().out)
|
||||
assert "All inline tags" in captured
|
||||
assert captured != Regex("┃ Keys +┃ Values +┃")
|
||||
assert captured != Regex("│ key1 +│ value1 +│")
|
||||
assert captured != Regex("│ key2 +│ value1 +│")
|
||||
assert captured != Regex("│ key4 +│ value1 +│")
|
||||
assert captured == Regex("#tag1 +#tag2 +#tag3")
|
||||
|
||||
|
||||
def test_print_metadata_5(capsys):
|
||||
"""Test print_metadata() method.
|
||||
|
||||
GIVEN calling print_metadata() with a VaultMetadata object
|
||||
WHEN KEYS is specified
|
||||
THEN print all the tags
|
||||
"""
|
||||
vm = VaultMetadata()
|
||||
vm.dict = {
|
||||
"key1": ["value1", "value2"],
|
||||
"key2": ["value1", "value2"],
|
||||
"key3": ["value1"],
|
||||
"key4": ["value1", "value2"],
|
||||
}
|
||||
vm.frontmatter = {"key1": ["value1"], "key2": ["value1", "value2"]}
|
||||
vm.inline_metadata = {
|
||||
"key1": ["value1", "value2"],
|
||||
"key3": ["value1"],
|
||||
"key4": ["value1", "value2"],
|
||||
}
|
||||
vm.tags = ["tag1", "tag2", "tag3"]
|
||||
|
||||
vm.print_metadata(area=MetadataType.KEYS)
|
||||
captured = remove_ansi(capsys.readouterr().out)
|
||||
assert "All Keys" in captured
|
||||
assert captured != Regex("┃ Keys +┃ Values +┃")
|
||||
assert captured != Regex("│ key1 +│ value1 +│")
|
||||
assert captured != Regex("│ key2 +│ value1 +│")
|
||||
assert captured != Regex("│ key4 +│ value1 +│")
|
||||
assert captured != Regex("#tag1 +#tag2 +#tag3")
|
||||
assert captured == Regex("key1 +key2 +key3 +key4")
|
||||
@@ -6,15 +6,174 @@ import typer
|
||||
|
||||
from obsidian_metadata._utils import (
|
||||
clean_dictionary,
|
||||
delete_from_dict,
|
||||
dict_contains,
|
||||
dict_keys_to_lower,
|
||||
dict_values_to_lists_strings,
|
||||
remove_markdown_sections,
|
||||
rename_in_dict,
|
||||
validate_csv_bulk_imports,
|
||||
)
|
||||
from tests.helpers import Regex, remove_ansi
|
||||
|
||||
|
||||
def test_delete_from_dict_1():
|
||||
"""Test delete_from_dict() function.
|
||||
|
||||
GIVEN a dictionary with values
|
||||
WHEN the delete_from_dict() function is called with a key that exists
|
||||
THEN the key should be deleted from the dictionary and the original dictionary should not be modified
|
||||
"""
|
||||
test_dict = {"key1": ["value1"], "key2": ["value2", "value3"], "key3": "value4"}
|
||||
|
||||
assert delete_from_dict(dictionary=test_dict, key="key1") == {
|
||||
"key2": ["value2", "value3"],
|
||||
"key3": "value4",
|
||||
}
|
||||
assert test_dict == {"key1": ["value1"], "key2": ["value2", "value3"], "key3": "value4"}
|
||||
|
||||
|
||||
def test_delete_from_dict_2():
|
||||
"""Test delete_from_dict() function.
|
||||
|
||||
GIVEN a dictionary with values
|
||||
WHEN the delete_from_dict() function is called with a key that does not exist
|
||||
THEN the dictionary should not be modified
|
||||
"""
|
||||
test_dict = {"key1": ["value1"], "key2": ["value2", "value3"], "key3": "value4"}
|
||||
|
||||
assert delete_from_dict(dictionary=test_dict, key="key5") == test_dict
|
||||
|
||||
|
||||
def test_delete_from_dict_3():
|
||||
"""Test delete_from_dict() function.
|
||||
|
||||
GIVEN a dictionary with values in a list
|
||||
WHEN the delete_from_dict() function is called with a key and value that exists
|
||||
THEN the value should be deleted from the specified key in dictionary
|
||||
"""
|
||||
test_dict = {"key1": ["value1"], "key2": ["value2", "value3"], "key3": "value4"}
|
||||
|
||||
assert delete_from_dict(dictionary=test_dict, key="key2", value="value3") == {
|
||||
"key1": ["value1"],
|
||||
"key2": ["value2"],
|
||||
"key3": "value4",
|
||||
}
|
||||
|
||||
|
||||
def test_delete_from_dict_4():
|
||||
"""Test delete_from_dict() function.
|
||||
|
||||
GIVEN a dictionary with values as strings
|
||||
WHEN the delete_from_dict() function is called with a key and value that exists
|
||||
THEN the value and key should be deleted from the dictionary
|
||||
"""
|
||||
test_dict = {"key1": ["value1"], "key2": ["value2", "value3"], "key3": "value4"}
|
||||
|
||||
assert delete_from_dict(dictionary=test_dict, key="key3", value="value4") == {
|
||||
"key1": ["value1"],
|
||||
"key2": ["value2", "value3"],
|
||||
}
|
||||
|
||||
|
||||
def test_delete_from_dict_5():
|
||||
"""Test delete_from_dict() function.
|
||||
|
||||
GIVEN a dictionary with values as strings
|
||||
WHEN the delete_from_dict() function is called with a key and value that does not exist
|
||||
THEN the dictionary should not be modified
|
||||
"""
|
||||
test_dict = {"key1": ["value1"], "key2": ["value2", "value3"], "key3": "value4"}
|
||||
|
||||
assert delete_from_dict(dictionary=test_dict, key="key3", value="value5") == test_dict
|
||||
|
||||
|
||||
def test_delete_from_dict_6():
|
||||
"""Test delete_from_dict() function.
|
||||
|
||||
GIVEN a dictionary with values as strings
|
||||
WHEN the delete_from_dict() function is called with a key regex that matches
|
||||
THEN the matching keys should be deleted from the dictionary
|
||||
"""
|
||||
test_dict = {"key1": ["value1"], "key2": ["value2", "value3"], "key3": "value4"}
|
||||
|
||||
assert delete_from_dict(dictionary=test_dict, key="key[23]", is_regex=True) == {
|
||||
"key1": ["value1"]
|
||||
}
|
||||
|
||||
|
||||
def test_delete_from_dict_7():
|
||||
"""Test delete_from_dict() function.
|
||||
|
||||
GIVEN a dictionary with values as strings
|
||||
WHEN the delete_from_dict() function is called with a key regex that does not match
|
||||
THEN no keys should be deleted from the dictionary
|
||||
"""
|
||||
test_dict = {"key1": ["value1"], "key2": ["value2", "value3"], "key3": "value4"}
|
||||
|
||||
assert delete_from_dict(dictionary=test_dict, key=r"key\d\d", is_regex=True) == test_dict
|
||||
|
||||
|
||||
def test_delete_from_dict_8():
|
||||
"""Test delete_from_dict() function.
|
||||
|
||||
GIVEN a dictionary with values as strings
|
||||
WHEN the delete_from_dict() function is called with a key and value regex that matches
|
||||
THEN the matching keys should be deleted from the dictionary
|
||||
"""
|
||||
test_dict = {"key1": ["value1"], "key2": ["value2", "value3"], "key3": "value4"}
|
||||
|
||||
assert delete_from_dict(dictionary=test_dict, key="key2", value=r"\w+", is_regex=True) == {
|
||||
"key1": ["value1"],
|
||||
"key2": [],
|
||||
"key3": "value4",
|
||||
}
|
||||
|
||||
|
||||
def test_delete_from_dict_9():
|
||||
"""Test delete_from_dict() function.
|
||||
|
||||
GIVEN a dictionary with values as strings
|
||||
WHEN the delete_from_dict() function is called with a key and value regex that does not match
|
||||
THEN no keys should be deleted from the dictionary
|
||||
"""
|
||||
test_dict = {"key1": ["value1"], "key2": ["value2", "value3"], "key3": "value4"}
|
||||
|
||||
assert (
|
||||
delete_from_dict(dictionary=test_dict, key=r"key2", value=r"^\d", is_regex=True)
|
||||
== test_dict
|
||||
)
|
||||
|
||||
|
||||
def test_delete_from_dict_10():
|
||||
"""Test delete_from_dict() function.
|
||||
|
||||
GIVEN a dictionary with values as strings
|
||||
WHEN the delete_from_dict() function is called with a key and value regex that matches
|
||||
THEN the matching keys should be deleted from the dictionary
|
||||
"""
|
||||
test_dict = {"key1": ["value1"], "key2": ["value2", "value3"], "key3": "value4"}
|
||||
|
||||
assert delete_from_dict(dictionary=test_dict, key="key3", value=r"\w+", is_regex=True) == {
|
||||
"key1": ["value1"],
|
||||
"key2": ["value2", "value3"],
|
||||
}
|
||||
|
||||
|
||||
def test_delete_from_dict_11():
|
||||
"""Test delete_from_dict() function.
|
||||
|
||||
GIVEN a dictionary with values as strings
|
||||
WHEN the delete_from_dict() function is called with a key regex that matches multiple and values that match
|
||||
THEN the values matching the associated keys should be deleted from the dictionary
|
||||
"""
|
||||
test_dict = {"key1": ["value1"], "key2": ["value2", "value3"], "key3": "value4"}
|
||||
|
||||
assert delete_from_dict(
|
||||
dictionary=test_dict, key=r"key[23]", value=r"\w+[34]$", is_regex=True
|
||||
) == {"key1": ["value1"], "key2": ["value2"]}
|
||||
|
||||
|
||||
def test_dict_contains() -> None:
|
||||
"""Test dict_contains."""
|
||||
d = {"key1": ["value1", "value2"], "key2": ["value3", "value4"], "key3": ["value5", "value6"]}
|
||||
@@ -82,6 +241,78 @@ def test_dict_values_to_lists_strings():
|
||||
}
|
||||
|
||||
|
||||
def test_rename_in_dict_1():
|
||||
"""Test rename_in_dict() function.
|
||||
|
||||
GIVEN a dictionary with values as a list
|
||||
WHEN the rename_in_dict() function is called with a key that does not exist
|
||||
THEN no keys should be renamed in the dictionary
|
||||
"""
|
||||
test_dict = {"key1": ["value1"], "key2": ["value2", "value3"]}
|
||||
|
||||
assert rename_in_dict(dictionary=test_dict, key="key4", value_1="key5") == test_dict
|
||||
|
||||
|
||||
def test_rename_in_dict_2():
|
||||
"""Test rename_in_dict() function.
|
||||
|
||||
GIVEN a dictionary with values as a list
|
||||
WHEN the rename_in_dict() function is called with a key that exists and a new value for the key
|
||||
THEN the key should be renamed in the returned dictionary and the original dictionary should not be modified
|
||||
"""
|
||||
test_dict = {"key1": ["value1"], "key2": ["value2", "value3"]}
|
||||
|
||||
assert rename_in_dict(dictionary=test_dict, key="key2", value_1="new_key") == {
|
||||
"key1": ["value1"],
|
||||
"new_key": ["value2", "value3"],
|
||||
}
|
||||
assert test_dict == {"key1": ["value1"], "key2": ["value2", "value3"]}
|
||||
|
||||
|
||||
def test_rename_in_dict_3():
|
||||
"""Test rename_in_dict() function.
|
||||
|
||||
GIVEN a dictionary with values as a list
|
||||
WHEN the rename_in_dict() function is called with a key that exists value that does not exist
|
||||
THEN the dictionary should not be modified
|
||||
"""
|
||||
test_dict = {"key1": ["value1"], "key2": ["value2", "value3"]}
|
||||
|
||||
assert (
|
||||
rename_in_dict(dictionary=test_dict, key="key2", value_1="no_value", value_2="new_value")
|
||||
== test_dict
|
||||
)
|
||||
|
||||
|
||||
def test_rename_in_dict_4():
|
||||
"""Test rename_in_dict() function.
|
||||
|
||||
GIVEN a dictionary with values as a list
|
||||
WHEN the rename_in_dict() function is called with a key that exists and a new value for a value
|
||||
THEN update the specified value in the dictionary
|
||||
"""
|
||||
test_dict = {"key1": ["value1"], "key2": ["value2", "value3"]}
|
||||
|
||||
assert rename_in_dict(
|
||||
dictionary=test_dict, key="key2", value_1="value2", value_2="new_value"
|
||||
) == {"key1": ["value1"], "key2": ["new_value", "value3"]}
|
||||
|
||||
|
||||
def test_rename_in_dict_5():
|
||||
"""Test rename_in_dict() function.
|
||||
|
||||
GIVEN a dictionary with values as a list
|
||||
WHEN the rename_in_dict() function is called with a key that exists and a an existing value for a renamed value
|
||||
THEN only one instance of the new value should be in the key
|
||||
"""
|
||||
test_dict = {"key1": ["value1"], "key2": ["value2", "value3"]}
|
||||
|
||||
assert rename_in_dict(dictionary=test_dict, key="key2", value_1="value2", value_2="value3") == {
|
||||
"key1": ["value1"],
|
||||
"key2": ["value3"],
|
||||
}
|
||||
|
||||
|
||||
def test_remove_markdown_sections():
|
||||
"""Test removing markdown sections."""
|
||||
text: str = """
|
||||
|
||||
Reference in New Issue
Block a user