- Add tagging system Python package with modular architecture (config, core, impl) - Create core interfaces for file discovery, content analysis, and tag generation - Implement content analyzer with language detection and topic extraction - Implement file discovery engine with directory scanning and filtering - Implement tag generator with hierarchical tag creation and consolidation - Add configuration management with example config and validation - Create comprehensive design and requirements documentation in .kiro/specs - Add pytest test suite with unit tests for models, interfaces, and config - Add setup.py, requirements.txt, and pytest.ini for package management - Add README.md with project overview and usage instructions - Update workspace.json with new project structure - Add Excalidraw diagram for system architecture visualization - Establish foundation for automated vault tagging and metadata management
193 lines
6.4 KiB
Python
193 lines
6.4 KiB
Python
"""Unit tests for core data models."""
|
|
|
|
import pytest
|
|
from datetime import datetime
|
|
from tagging_system.core.models import (
|
|
FileInfo,
|
|
ContentAnalysis,
|
|
TagStructure,
|
|
FrontmatterData,
|
|
ValidationResult,
|
|
ContentType,
|
|
LanguageInfo
|
|
)
|
|
|
|
|
|
class TestFileInfo:
|
|
"""Test FileInfo model."""
|
|
|
|
def test_file_info_creation(self):
|
|
"""Test FileInfo creation with required fields."""
|
|
file_info = FileInfo(
|
|
path="test/file.md",
|
|
name="file.md",
|
|
directory="test",
|
|
extension=".md",
|
|
size=100,
|
|
created=datetime.now(),
|
|
modified=datetime.now()
|
|
)
|
|
|
|
assert file_info.path == "test/file.md"
|
|
assert file_info.name == "file.md"
|
|
assert file_info.is_markdown is True
|
|
assert file_info.relative_path == "test/file.md"
|
|
|
|
def test_is_markdown_detection(self):
|
|
"""Test markdown file detection."""
|
|
md_file = FileInfo("test.md", "test.md", ".", ".md", 100, datetime.now(), datetime.now())
|
|
txt_file = FileInfo("test.txt", "test.txt", ".", ".txt", 100, datetime.now(), datetime.now())
|
|
|
|
assert md_file.is_markdown is True
|
|
assert txt_file.is_markdown is False
|
|
|
|
|
|
class TestContentAnalysis:
|
|
"""Test ContentAnalysis model."""
|
|
|
|
def test_content_analysis_creation(self):
|
|
"""Test ContentAnalysis creation."""
|
|
analysis = ContentAnalysis(
|
|
language=LanguageInfo.ENGLISH,
|
|
content_type=ContentType.NOTE,
|
|
topics=["ai", "ml"]
|
|
)
|
|
|
|
assert analysis.language == LanguageInfo.ENGLISH
|
|
assert analysis.content_type == ContentType.NOTE
|
|
assert analysis.topics == ["ai", "ml"]
|
|
assert analysis.complexity == "basic" # Default value
|
|
|
|
def test_complexity_validation(self):
|
|
"""Test complexity validation in post_init."""
|
|
analysis = ContentAnalysis(
|
|
language=LanguageInfo.ENGLISH,
|
|
content_type=ContentType.NOTE,
|
|
topics=[],
|
|
complexity="invalid"
|
|
)
|
|
|
|
assert analysis.complexity == "basic" # Should default to basic
|
|
|
|
|
|
class TestTagStructure:
|
|
"""Test TagStructure model."""
|
|
|
|
def test_tag_structure_creation(self):
|
|
"""Test TagStructure creation."""
|
|
tags = TagStructure(
|
|
primary=["project"],
|
|
hierarchical=["tech/ai"],
|
|
content=["python"],
|
|
meta=["lang/en"],
|
|
custom=["custom"]
|
|
)
|
|
|
|
assert tags.primary == ["project"]
|
|
assert tags.hierarchical == ["tech/ai"]
|
|
assert tags.content == ["python"]
|
|
assert tags.meta == ["lang/en"]
|
|
assert tags.custom == ["custom"]
|
|
|
|
def test_all_tags_method(self):
|
|
"""Test all_tags method returns unique tags."""
|
|
tags = TagStructure(
|
|
primary=["project", "duplicate"],
|
|
hierarchical=["tech/ai"],
|
|
content=["python", "duplicate"], # Duplicate tag
|
|
meta=["lang/en"],
|
|
custom=["custom"]
|
|
)
|
|
|
|
all_tags = tags.all_tags()
|
|
# Expected unique tags: project, duplicate, tech/ai, python, lang/en, custom = 6 tags
|
|
assert len(all_tags) == 6
|
|
assert "duplicate" in all_tags
|
|
assert "project" in all_tags
|
|
assert "tech/ai" in all_tags
|
|
assert "python" in all_tags
|
|
assert "lang/en" in all_tags
|
|
assert "custom" in all_tags
|
|
|
|
# Test that duplicates are actually removed by checking set behavior
|
|
unique_tags = set(all_tags)
|
|
assert len(unique_tags) == len(all_tags) # No duplicates should exist
|
|
|
|
# Test with actual duplicates to verify deduplication works
|
|
tags_with_more_duplicates = TagStructure(
|
|
primary=["tag1", "tag2"],
|
|
hierarchical=["tag1"], # Duplicate of primary
|
|
content=["tag2", "tag3"], # Duplicate of primary
|
|
meta=["tag3"], # Duplicate of content
|
|
custom=["tag4"]
|
|
)
|
|
deduplicated = tags_with_more_duplicates.all_tags()
|
|
assert len(deduplicated) == 4 # tag1, tag2, tag3, tag4
|
|
assert len(set(deduplicated)) == len(deduplicated)
|
|
|
|
|
|
class TestFrontmatterData:
|
|
"""Test FrontmatterData model."""
|
|
|
|
def test_frontmatter_data_creation(self):
|
|
"""Test FrontmatterData creation."""
|
|
frontmatter = FrontmatterData(
|
|
title="Test",
|
|
tags=["tag1", "tag2"],
|
|
created="2024-01-01",
|
|
type="note"
|
|
)
|
|
|
|
assert frontmatter.title == "Test"
|
|
assert frontmatter.tags == ["tag1", "tag2"]
|
|
assert frontmatter.created == "2024-01-01"
|
|
assert frontmatter.type == "note"
|
|
|
|
def test_to_dict_method(self):
|
|
"""Test to_dict method excludes None values."""
|
|
frontmatter = FrontmatterData(
|
|
title="Test",
|
|
tags=["tag1"],
|
|
created="2024-01-01",
|
|
updated=None, # Should be excluded
|
|
custom_fields={"custom": "value"}
|
|
)
|
|
|
|
result = frontmatter.to_dict()
|
|
|
|
assert result["title"] == "Test"
|
|
assert result["tags"] == ["tag1"]
|
|
assert result["created"] == "2024-01-01"
|
|
assert "updated" not in result # None values excluded
|
|
assert result["custom"] == "value" # Custom fields included
|
|
|
|
|
|
class TestValidationResult:
|
|
"""Test ValidationResult model."""
|
|
|
|
def test_validation_result_creation(self):
|
|
"""Test ValidationResult creation."""
|
|
result = ValidationResult(is_valid=True)
|
|
|
|
assert result.is_valid is True
|
|
assert result.errors == []
|
|
assert result.warnings == []
|
|
assert result.suggestions == []
|
|
|
|
def test_add_error_sets_invalid(self):
|
|
"""Test that adding error sets is_valid to False."""
|
|
result = ValidationResult(is_valid=True)
|
|
result.add_error("Test error")
|
|
|
|
assert result.is_valid is False
|
|
assert "Test error" in result.errors
|
|
|
|
def test_add_warning_and_suggestion(self):
|
|
"""Test adding warnings and suggestions."""
|
|
result = ValidationResult(is_valid=True)
|
|
result.add_warning("Test warning")
|
|
result.add_suggestion("Test suggestion")
|
|
|
|
assert result.is_valid is True # Warnings don't affect validity
|
|
assert "Test warning" in result.warnings
|
|
assert "Test suggestion" in result.suggestions |