Skip to main content
Glama

basic-memory

test_markdown_plugins.py7.41 kB
"""Tests for markdown plugins.""" from textwrap import dedent from markdown_it import MarkdownIt from markdown_it.token import Token from basic_memory.markdown.plugins import ( observation_plugin, relation_plugin, is_observation, is_explicit_relation, parse_relation, parse_inline_relations, ) def test_observation_plugin(): """Test observation plugin.""" # Set up markdown-it instance md = MarkdownIt().use(observation_plugin) # Test basic observation with all features content = dedent(""" - [design] Basic observation #tag1 #tag2 (with context) """) tokens = md.parse(content) token = [t for t in tokens if t.type == "inline"][0] assert "observation" in token.meta obs = token.meta["observation"] assert obs["category"] == "design" assert obs["content"] == "Basic observation #tag1 #tag2" assert set(obs["tags"]) == {"tag1", "tag2"} assert obs["context"] == "with context" # Test without category content = "- Basic observation #tag1 (context)" token = [t for t in md.parse(content) if t.type == "inline"][0] obs = token.meta["observation"] assert obs["category"] is None assert obs["content"] == "Basic observation #tag1" assert obs["tags"] == ["tag1"] assert obs["context"] == "context" # Test without tags content = "- [note] Basic observation (context)" token = [t for t in md.parse(content) if t.type == "inline"][0] obs = token.meta["observation"] assert obs["category"] == "note" assert obs["content"] == "Basic observation" assert obs["tags"] is None assert obs["context"] == "context" def test_observation_edge_cases(): """Test observation parsing edge cases.""" # Test non-inline token token = Token("paragraph", "", 0) assert not is_observation(token) # Test empty content token = Token("inline", "", 0) assert not is_observation(token) # Test markdown task token = Token("inline", "[ ] Task item", 0) assert not is_observation(token) # Test completed task token = Token("inline", "[x] Done task", 0) assert not is_observation(token) # Test in-progress task token = Token("inline", "[-] Ongoing task", 0) assert not is_observation(token) def test_observation_excludes_markdown_and_wiki_links(): """Test that markdown links and wiki links are NOT parsed as observations. This test validates the fix for issue #247 where: - [text](url) markdown links were incorrectly parsed as observations - [[text]] wiki links were incorrectly parsed as observations """ # Test markdown links are NOT observations token = Token("inline", "[Click here](https://example.com)", 0) assert not is_observation(token), "Markdown links should not be parsed as observations" token = Token("inline", "[Documentation](./docs/readme.md)", 0) assert not is_observation(token), "Relative markdown links should not be parsed as observations" token = Token("inline", "[Empty link]()", 0) assert not is_observation(token), "Empty markdown links should not be parsed as observations" # Test wiki links are NOT observations token = Token("inline", "[[SomeWikiPage]]", 0) assert not is_observation(token), "Wiki links should not be parsed as observations" token = Token("inline", "[[Multi Word Page]]", 0) assert not is_observation(token), "Multi-word wiki links should not be parsed as observations" # Test nested brackets are NOT observations token = Token("inline", "[[Nested [[Inner]] Link]]", 0) assert not is_observation(token), "Nested wiki links should not be parsed as observations" # Test valid observations still work (should return True) token = Token("inline", "[category] This is a valid observation", 0) assert is_observation(token), "Valid observations should still be parsed correctly" token = Token("inline", "[design] Valid observation #tag", 0) assert is_observation(token), "Valid observations with tags should still work" token = Token("inline", "Just some text #tag", 0) assert is_observation(token), "Tag-only observations should still work" # Test edge cases that should NOT be observations token = Token("inline", "[]Empty brackets", 0) assert not is_observation(token), "Empty category brackets should not be observations" token = Token("inline", "[category]No space after category", 0) assert not is_observation(token), "No space after category should not be valid observation" def test_relation_plugin(): """Test relation plugin.""" md = MarkdownIt().use(relation_plugin) # Test explicit relation with all features content = dedent(""" - implements [[Component]] (with context) """) tokens = md.parse(content) token = [t for t in tokens if t.type == "inline"][0] assert "relations" in token.meta rel = token.meta["relations"][0] assert rel["type"] == "implements" assert rel["target"] == "Component" assert rel["context"] == "with context" # Test implicit relations in text content = "Some text with a [[Link]] and [[Another Link]]" token = [t for t in md.parse(content) if t.type == "inline"][0] rels = token.meta["relations"] assert len(rels) == 2 assert rels[0]["type"] == "links to" assert rels[0]["target"] == "Link" assert rels[1]["target"] == "Another Link" def test_relation_edge_cases(): """Test relation parsing edge cases.""" # Test non-inline token token = Token("paragraph", "", 0) assert not is_explicit_relation(token) # Test empty content token = Token("inline", "", 0) assert not is_explicit_relation(token) # Test incomplete relation (missing target) token = Token("inline", "relates_to [[]]", 0) result = parse_relation(token) assert result is None # Test non-relation content token = Token("inline", "Just some text", 0) result = parse_relation(token) assert result is None # Test invalid inline link (empty target) assert not parse_inline_relations("Text with [[]] empty link") # Test nested links (avoid duplicates) result = parse_inline_relations("Text with [[Outer [[Inner]] Link]]") assert len(result) == 1 assert result[0]["target"] == "Outer [[Inner]] Link" def test_combined_plugins(): """Test both plugins working together.""" md = MarkdownIt().use(observation_plugin).use(relation_plugin) content = dedent(""" # Section - [design] Observation with [[Link]] #tag (context) - implements [[Component]] (details) - Just a [[Reference]] in text Some text with a [[Link]] reference. """) tokens = md.parse(content) inline_tokens = [t for t in tokens if t.type == "inline"] # First token has both observation and relation obs_token = inline_tokens[1] assert "observation" in obs_token.meta assert "relations" in obs_token.meta # Second token has explicit relation rel_token = inline_tokens[2] assert "relations" in rel_token.meta rel = rel_token.meta["relations"][0] assert rel["type"] == "implements" # Third token has implicit relation text_token = inline_tokens[4] assert "relations" in text_token.meta link = text_token.meta["relations"][0] assert link["type"] == "links to"

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/basicmachines-co/basic-memory'

If you have feedback or need assistance with the MCP directory API, please join our Discord server