Files
vault-para/tests/test_config.py
windyboy f99056a099 feat(tagging-system): Add comprehensive tagging system implementation
- 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
2025-12-31 08:37:16 +08:00

178 lines
5.9 KiB
Python

"""Unit tests for configuration system."""
import pytest
import json
from pathlib import Path
from tagging_system.config import (
TaggingConfig,
DirectoryMapping,
TagHierarchy,
SensitivePatterns,
load_config,
save_config
)
class TestDirectoryMapping:
"""Test DirectoryMapping model."""
def test_directory_mapping_creation(self):
"""Test DirectoryMapping creation."""
mapping = DirectoryMapping(
pattern="100-project",
primary_tag="project",
hierarchical_tags=["tech"],
exclude_patterns=["*.tmp"]
)
assert mapping.pattern == "100-project"
assert mapping.primary_tag == "project"
assert mapping.hierarchical_tags == ["tech"]
assert mapping.exclude_patterns == ["*.tmp"]
class TestTagHierarchy:
"""Test TagHierarchy model."""
def test_tag_hierarchy_creation(self):
"""Test TagHierarchy creation."""
hierarchy = TagHierarchy(
root="tech",
children={"ai": TagHierarchy("ai")},
aliases=["technology"]
)
assert hierarchy.root == "tech"
assert "ai" in hierarchy.children
assert hierarchy.aliases == ["technology"]
def test_get_full_path(self):
"""Test get_full_path method."""
hierarchy = TagHierarchy("tech")
assert hierarchy.get_full_path() == "tech"
assert hierarchy.get_full_path("ai") == "tech/ai"
assert hierarchy.get_full_path("ai/llm") == "tech/ai/llm"
class TestSensitivePatterns:
"""Test SensitivePatterns model."""
def test_sensitive_patterns_defaults(self):
"""Test SensitivePatterns default values."""
patterns = SensitivePatterns()
assert len(patterns.credential_patterns) > 0
assert len(patterns.personal_patterns) > 0
assert len(patterns.financial_patterns) > 0
assert any("api" in pattern for pattern in patterns.credential_patterns)
class TestTaggingConfig:
"""Test TaggingConfig model."""
def test_tagging_config_defaults(self):
"""Test TaggingConfig default values."""
config = TaggingConfig()
assert len(config.directory_mappings) > 0
assert len(config.tag_hierarchies) > 0
assert len(config.excluded_directories) > 0
assert config.tag_format_rules["case"] == "kebab"
def test_get_directory_mapping(self):
"""Test get_directory_mapping method."""
config = TaggingConfig()
mapping = config.get_directory_mapping("100-project/AI/test.md")
assert mapping is not None
assert mapping.primary_tag == "project"
no_mapping = config.get_directory_mapping("unknown/path")
assert no_mapping is None
def test_get_tag_hierarchy(self):
"""Test get_tag_hierarchy method."""
config = TaggingConfig()
tech_hierarchy = config.get_tag_hierarchy("tech")
assert tech_hierarchy is not None
assert tech_hierarchy.root == "tech"
unknown_hierarchy = config.get_tag_hierarchy("unknown")
assert unknown_hierarchy is None
def test_is_excluded_directory(self):
"""Test is_excluded_directory method."""
config = TaggingConfig()
assert config.is_excluded_directory(".obsidian/plugins") is True
assert config.is_excluded_directory("100-project/AI") is False
def test_is_excluded_file(self):
"""Test is_excluded_file method."""
config = TaggingConfig()
assert config.is_excluded_file("test.pyc") is True
assert config.is_excluded_file(".DS_Store") is True
assert config.is_excluded_file("test.md") is False
class TestConfigLoading:
"""Test configuration loading and saving."""
def test_load_default_config(self):
"""Test loading default config when no file exists."""
config = load_config()
assert isinstance(config, TaggingConfig)
assert len(config.directory_mappings) > 0
def test_load_config_creates_default_file(self, tmp_path: Path):
"""Test that load_config creates default file when path doesn't exist."""
config_path = tmp_path / "config.yaml"
config = load_config(config_path)
assert isinstance(config, TaggingConfig)
assert config_path.exists()
def test_save_and_load_config(self, tmp_path: Path):
"""Test saving and loading configuration."""
config_path = tmp_path / "test_config.yaml"
original_config = TaggingConfig()
original_config.excluded_directories.append("test_exclude")
save_config(original_config, config_path)
loaded_config = load_config(config_path)
assert config_path.exists()
assert "test_exclude" in loaded_config.excluded_directories
def test_load_json_config(self, tmp_path: Path):
"""Test loading JSON configuration."""
config_path = tmp_path / "config.json"
config_data = {
"excluded_directories": [".test", ".custom"],
"tag_format_rules": {"case": "snake"}
}
with open(config_path, 'w') as f:
json.dump(config_data, f)
config = load_config(config_path)
assert ".test" in config.excluded_directories
assert ".custom" in config.excluded_directories
assert config.tag_format_rules["case"] == "snake"
def test_load_invalid_config_returns_default(self, tmp_path: Path):
"""Test that invalid config file returns default config."""
config_path = tmp_path / "invalid.yaml"
config_path.write_text("invalid: yaml: content: [")
config = load_config(config_path)
# Should return default config on error
assert isinstance(config, TaggingConfig)
assert len(config.directory_mappings) > 0