mirror of
https://github.com/natelandau/obsidian-metadata.git
synced 2025-11-17 01:13:39 -05:00
feat: greatly improve capturing all formats of inline metadata (#41)
feat: greatly improve capturing metadata all formats of inline metadata
This commit is contained in:
@@ -6,13 +6,9 @@ import typer
|
||||
|
||||
from obsidian_metadata._utils import (
|
||||
clean_dictionary,
|
||||
delete_from_dict,
|
||||
dict_contains,
|
||||
dict_keys_to_lower,
|
||||
dict_values_to_lists_strings,
|
||||
inline_metadata_from_string,
|
||||
merge_dictionaries,
|
||||
remove_markdown_sections,
|
||||
rename_in_dict,
|
||||
validate_csv_bulk_imports,
|
||||
)
|
||||
@@ -84,163 +80,6 @@ def test_clean_dictionary_6():
|
||||
}
|
||||
|
||||
|
||||
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_1():
|
||||
"""Test dict_contains() function.
|
||||
|
||||
@@ -342,140 +181,6 @@ def test_dict_keys_to_lower() -> None:
|
||||
assert dict_keys_to_lower(test_dict) == {"key1": "Value1", "key2": "Value2", "key3": "Value3"}
|
||||
|
||||
|
||||
def test_dict_values_to_lists_strings_1():
|
||||
"""Test the dict_values_to_lists_strings() function.
|
||||
|
||||
GIVEN a dictionary passed to the dict_values_to_lists_strings() function
|
||||
WHEN the dictionary is empty
|
||||
THEN the function should return an empty dictionary
|
||||
"""
|
||||
assert dict_values_to_lists_strings({}) == {}
|
||||
assert dict_values_to_lists_strings({}, strip_null_values=True) == {}
|
||||
|
||||
|
||||
def test_dict_values_to_lists_strings_2():
|
||||
"""Test the dict_values_to_lists_strings() function.
|
||||
|
||||
GIVEN a dictionary passed to the dict_values_to_lists_strings() function
|
||||
WHEN the dictionary values are already lists of strings
|
||||
THEN the function should return the dictionary
|
||||
"""
|
||||
test_dict = {"key1": ["value1"], "key2": ["value2", "value3"]}
|
||||
assert dict_values_to_lists_strings(test_dict) == {
|
||||
"key1": ["value1"],
|
||||
"key2": ["value2", "value3"],
|
||||
}
|
||||
assert dict_values_to_lists_strings(test_dict, strip_null_values=True) == {
|
||||
"key1": ["value1"],
|
||||
"key2": ["value2", "value3"],
|
||||
}
|
||||
|
||||
|
||||
def test_dict_values_to_lists_strings_3():
|
||||
"""Test the dict_values_to_lists_strings() function.
|
||||
|
||||
GIVEN a dictionary passed to the dict_values_to_lists_strings() function
|
||||
WHEN the a value is None and strip_null_values is False
|
||||
THEN then convert None to an empty string
|
||||
"""
|
||||
test_dict = {"key1": None, "key2": ["value", None]}
|
||||
assert dict_values_to_lists_strings(test_dict) == {"key1": [""], "key2": ["", "value"]}
|
||||
|
||||
|
||||
def test_dict_values_to_lists_strings_4():
|
||||
"""Test the dict_values_to_lists_strings() function.
|
||||
|
||||
GIVEN a dictionary passed to the dict_values_to_lists_strings() function
|
||||
WHEN the a value is None and strip_null_values is True
|
||||
THEN remove null values
|
||||
"""
|
||||
test_dict = {"key1": None, "key2": ["value", None]}
|
||||
assert dict_values_to_lists_strings(test_dict, strip_null_values=True) == {
|
||||
"key1": [],
|
||||
"key2": ["value"],
|
||||
}
|
||||
|
||||
|
||||
def test_dict_values_to_lists_strings_5():
|
||||
"""Test the dict_values_to_lists_strings() function.
|
||||
|
||||
GIVEN a dictionary passed to the dict_values_to_lists_strings() function
|
||||
WHEN the a value is a string "None" and strip_null_values is True or False
|
||||
THEN ensure the value is not removed
|
||||
"""
|
||||
test_dict = {"key1": "None", "key2": [None, "None"]}
|
||||
assert dict_values_to_lists_strings(test_dict) == {"key1": ["None"], "key2": ["", "None"]}
|
||||
assert dict_values_to_lists_strings(test_dict, strip_null_values=True) == {
|
||||
"key1": [],
|
||||
"key2": ["None"],
|
||||
}
|
||||
|
||||
|
||||
def test_dict_values_to_lists_strings_6():
|
||||
"""Test the dict_values_to_lists_strings() function.
|
||||
|
||||
GIVEN a dictionary passed to the dict_values_to_lists_strings() function
|
||||
WHEN the a value is another dictionary
|
||||
THEN ensure the values in the inner dictionary are converted to lists of strings
|
||||
"""
|
||||
test_dict = {"key1": {"key2": "value2", "key3": ["value3", None]}}
|
||||
assert dict_values_to_lists_strings(test_dict) == {
|
||||
"key1": {"key2": ["value2"], "key3": ["", "value3"]}
|
||||
}
|
||||
assert dict_values_to_lists_strings(test_dict, strip_null_values=True) == {
|
||||
"key1": {"key2": ["value2"], "key3": ["value3"]}
|
||||
}
|
||||
|
||||
|
||||
def test_inline_metadata_from_string_1():
|
||||
"""Test inline_metadata_from_string() function.
|
||||
|
||||
GIVEN a string
|
||||
WHEN the string is empty
|
||||
THEN the function should return an empty list.
|
||||
"""
|
||||
assert inline_metadata_from_string("") == []
|
||||
|
||||
|
||||
def test_inline_metadata_from_string_2():
|
||||
"""Test inline_metadata_from_string() function.
|
||||
|
||||
GIVEN a string
|
||||
WHEN the string contains nothing matching the inline metadata regex
|
||||
THEN the function should return an empty list.
|
||||
"""
|
||||
assert inline_metadata_from_string("this is content that has no inline metadata") == []
|
||||
|
||||
|
||||
def test_inline_metadata_from_string_3():
|
||||
"""Test inline_metadata_from_string() function.
|
||||
|
||||
GIVEN a string
|
||||
WHEN the string contains inline metadata
|
||||
THEN the function should return the key value pair as a tuple within a list.
|
||||
"""
|
||||
assert inline_metadata_from_string("test::test") == [("test", "test")]
|
||||
|
||||
|
||||
def test_inline_metadata_from_string_4():
|
||||
"""Test inline_metadata_from_string() function.
|
||||
|
||||
GIVEN a string
|
||||
WHEN the string contains multiple matches of inline metadata
|
||||
THEN the function should return the key value pairs as a tuple within a list.
|
||||
"""
|
||||
content = """
|
||||
test::test
|
||||
paragraph [key::value] paragraph
|
||||
> test2::test2
|
||||
"""
|
||||
assert inline_metadata_from_string(content) == [
|
||||
("test", "test"),
|
||||
("key", "value"),
|
||||
("test2", "test2"),
|
||||
]
|
||||
|
||||
|
||||
def test_merge_dictionaries_1():
|
||||
"""Test merge_dictionaries() function.
|
||||
|
||||
@@ -661,199 +366,6 @@ def test_rename_in_dict_5():
|
||||
}
|
||||
|
||||
|
||||
def test_remove_markdown_sections_1():
|
||||
"""Test remove_markdown_sections() function.
|
||||
|
||||
GIVEN a string with markdown sections
|
||||
WHEN the remove_markdown_sections() function is called with the default arguments
|
||||
THEN return the string without removing any markdown sections
|
||||
"""
|
||||
text: str = """
|
||||
---
|
||||
key: value
|
||||
---
|
||||
|
||||
# heading
|
||||
|
||||
```bash
|
||||
echo "Hello world"
|
||||
```
|
||||
|
||||
Lorem ipsum `inline_code` lorem ipsum.
|
||||
```
|
||||
echo "foo bar"
|
||||
```
|
||||
|
||||
---
|
||||
dd
|
||||
---
|
||||
"""
|
||||
|
||||
assert remove_markdown_sections(text) == text
|
||||
|
||||
|
||||
def test_remove_markdown_sections_2():
|
||||
"""Test remove_markdown_sections() function.
|
||||
|
||||
GIVEN a string with markdown sections
|
||||
WHEN the remove_markdown_sections() function is called with strip_codeblocks set to True
|
||||
THEN return the string without the codeblocks
|
||||
"""
|
||||
text: str = """
|
||||
---
|
||||
key: value
|
||||
---
|
||||
|
||||
# heading
|
||||
|
||||
```bash
|
||||
echo "Hello world"
|
||||
```
|
||||
|
||||
Lorem ipsum `inline_code` lorem ipsum.
|
||||
```
|
||||
echo "foo bar"
|
||||
```
|
||||
|
||||
---
|
||||
dd
|
||||
---
|
||||
"""
|
||||
result = remove_markdown_sections(text, strip_codeblocks=True)
|
||||
assert "inline_code" in result
|
||||
assert "```bash" not in result
|
||||
assert "```" not in result
|
||||
assert "foo" not in result
|
||||
assert "world" not in result
|
||||
assert "key: value" in result
|
||||
assert "heading" in result
|
||||
assert "Lorem ipsum" in result
|
||||
assert "---\n" in result
|
||||
assert "dd" in result
|
||||
|
||||
|
||||
def test_remove_markdown_sections_3():
|
||||
"""Test remove_markdown_sections() function.
|
||||
|
||||
GIVEN a string with markdown sections
|
||||
WHEN the remove_markdown_sections() function is called with strip_inlinecode set to True
|
||||
THEN return the string without the inline code
|
||||
"""
|
||||
text: str = """
|
||||
---
|
||||
key: value
|
||||
---
|
||||
|
||||
# heading
|
||||
|
||||
```bash
|
||||
echo "Hello world"
|
||||
```
|
||||
|
||||
Lorem ipsum `inline_code` lorem ipsum.
|
||||
```
|
||||
echo "foo bar"
|
||||
```
|
||||
|
||||
---
|
||||
dd
|
||||
---
|
||||
"""
|
||||
result = remove_markdown_sections(text, strip_inlinecode=True)
|
||||
assert "`inline_code`" not in result
|
||||
assert "```bash" in result
|
||||
assert "```" in result
|
||||
assert "foo" in result
|
||||
assert "world" in result
|
||||
assert "key: value" in result
|
||||
assert "heading" in result
|
||||
assert "Lorem ipsum" in result
|
||||
assert "---\n" in result
|
||||
assert "dd" in result
|
||||
|
||||
|
||||
def test_remove_markdown_sections_4():
|
||||
"""Test remove_markdown_sections() function.
|
||||
|
||||
GIVEN a string with markdown sections
|
||||
WHEN the remove_markdown_sections() function is called with strip_frontmatter set to True
|
||||
THEN return the string without the frontmatter
|
||||
"""
|
||||
text: str = """
|
||||
---
|
||||
key: value
|
||||
---
|
||||
|
||||
# heading
|
||||
|
||||
```bash
|
||||
echo "Hello world"
|
||||
```
|
||||
|
||||
Lorem ipsum `inline_code` lorem ipsum.
|
||||
```
|
||||
echo "foo bar"
|
||||
```
|
||||
|
||||
---
|
||||
dd
|
||||
---
|
||||
"""
|
||||
result = remove_markdown_sections(text, strip_frontmatter=True)
|
||||
assert "`inline_code`" in result
|
||||
assert "```bash" in result
|
||||
assert "```" in result
|
||||
assert "foo" in result
|
||||
assert "world" in result
|
||||
assert "key: value" not in result
|
||||
assert "heading" in result
|
||||
assert "Lorem ipsum" in result
|
||||
assert "---\n" in result
|
||||
assert "dd" in result
|
||||
|
||||
|
||||
def test_remove_markdown_sections_5():
|
||||
"""Test remove_markdown_sections() function.
|
||||
|
||||
GIVEN a string with markdown sections
|
||||
WHEN the remove_markdown_sections() function is called with all arguments set to True
|
||||
THEN return the string without the frontmatter, inline code, and codeblocks
|
||||
"""
|
||||
text: str = """
|
||||
---
|
||||
key: value
|
||||
---
|
||||
|
||||
# heading
|
||||
|
||||
```bash
|
||||
echo "Hello world"
|
||||
```
|
||||
|
||||
Lorem ipsum `inline_code` lorem ipsum.
|
||||
```
|
||||
echo "foo bar"
|
||||
```
|
||||
|
||||
---
|
||||
dd
|
||||
---
|
||||
"""
|
||||
result = remove_markdown_sections(
|
||||
text, strip_frontmatter=True, strip_inlinecode=True, strip_codeblocks=True
|
||||
)
|
||||
assert "`inline_code`" not in result
|
||||
assert "bash" not in result
|
||||
assert "```" not in result
|
||||
assert "foo" not in result
|
||||
assert "world" not in result
|
||||
assert "key: value" not in result
|
||||
assert "heading" in result
|
||||
assert "Lorem ipsum" in result
|
||||
assert "---\n" in result
|
||||
assert "dd" in result
|
||||
|
||||
|
||||
def test_validate_csv_bulk_imports_1(tmp_path):
|
||||
"""Test the validate_csv_bulk_imports function.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user