This commit is contained in:
223
tests/test_config.py
Normal file
223
tests/test_config.py
Normal file
@@ -0,0 +1,223 @@
|
|||||||
|
"""Unit tests for configuration loading and validation."""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import tempfile
|
||||||
|
from pathlib import Path
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from dev_env_sync.core.config import ConfigLoader, ConfigSchema, ConfigParseError
|
||||||
|
|
||||||
|
|
||||||
|
class TestConfigLoader:
|
||||||
|
"""Tests for ConfigLoader class."""
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def sample_yaml_content(self):
|
||||||
|
"""Sample YAML configuration content."""
|
||||||
|
return '''
|
||||||
|
version: "1.0"
|
||||||
|
name: "Test Environment"
|
||||||
|
description: "Test configuration"
|
||||||
|
|
||||||
|
dotfiles:
|
||||||
|
bashrc:
|
||||||
|
source: ./dotfiles/.bashrc
|
||||||
|
target: ~/.bashrc
|
||||||
|
backup: true
|
||||||
|
vimrc:
|
||||||
|
source: ./dotfiles/.vimrc
|
||||||
|
target: ~/.vimrc
|
||||||
|
|
||||||
|
shell:
|
||||||
|
shell: bash
|
||||||
|
merge_strategy: replace
|
||||||
|
|
||||||
|
editors:
|
||||||
|
vscode:
|
||||||
|
settings:
|
||||||
|
settings_file: ./editors/vscode/settings.json
|
||||||
|
extensions:
|
||||||
|
- name: ms-python.python
|
||||||
|
|
||||||
|
packages:
|
||||||
|
- name: brew
|
||||||
|
packages:
|
||||||
|
- git
|
||||||
|
- neovim
|
||||||
|
|
||||||
|
backup:
|
||||||
|
enabled: true
|
||||||
|
directory: ~/.dev-env-sync-backups
|
||||||
|
timestamp_format: "%Y%m%d_%H%M%S"
|
||||||
|
'''
|
||||||
|
|
||||||
|
def test_load_valid_config(self, sample_yaml_content, temp_dir):
|
||||||
|
"""Test loading a valid configuration file."""
|
||||||
|
config_file = temp_dir / "config.yml"
|
||||||
|
config_file.write_text(sample_yaml_content)
|
||||||
|
|
||||||
|
loader = ConfigLoader(str(config_file))
|
||||||
|
config = loader.load()
|
||||||
|
|
||||||
|
assert config is not None
|
||||||
|
assert config.version == "1.0"
|
||||||
|
assert config.name == "Test Environment"
|
||||||
|
assert len(config.dotfiles) == 2
|
||||||
|
assert "bashrc" in config.dotfiles
|
||||||
|
assert "vimrc" in config.dotfiles
|
||||||
|
|
||||||
|
def test_load_minimal_config(self, temp_dir):
|
||||||
|
"""Test loading a minimal configuration file."""
|
||||||
|
config_file = temp_dir / "minimal.yml"
|
||||||
|
config_file.write_text('version: "1.0"\nname: "Minimal"')
|
||||||
|
|
||||||
|
loader = ConfigLoader(str(config_file))
|
||||||
|
config = loader.load()
|
||||||
|
|
||||||
|
assert config is not None
|
||||||
|
assert config.version == "1.0"
|
||||||
|
assert config.name == "Minimal"
|
||||||
|
assert len(config.dotfiles) == 0
|
||||||
|
|
||||||
|
def test_dotfiles_parsing(self, sample_yaml_content, temp_dir):
|
||||||
|
"""Test parsing dotfiles configuration."""
|
||||||
|
config_file = temp_dir / "config.yml"
|
||||||
|
config_file.write_text(sample_yaml_content)
|
||||||
|
|
||||||
|
loader = ConfigLoader(str(config_file))
|
||||||
|
config = loader.load()
|
||||||
|
|
||||||
|
assert "bashrc" in config.dotfiles
|
||||||
|
bashrc = config.dotfiles["bashrc"]
|
||||||
|
assert bashrc.source == "./dotfiles/.bashrc"
|
||||||
|
assert bashrc.target == "~/.bashrc"
|
||||||
|
assert bashrc.backup == True
|
||||||
|
|
||||||
|
def test_packages_parsing(self, sample_yaml_content, temp_dir):
|
||||||
|
"""Test parsing packages configuration."""
|
||||||
|
config_file = temp_dir / "config.yml"
|
||||||
|
config_file.write_text(sample_yaml_content)
|
||||||
|
|
||||||
|
loader = ConfigLoader(str(config_file))
|
||||||
|
config = loader.load()
|
||||||
|
|
||||||
|
assert len(config.packages) == 1
|
||||||
|
brew_pkg = config.packages[0]
|
||||||
|
assert brew_pkg.name == "brew"
|
||||||
|
assert len(brew_pkg.packages) == 2
|
||||||
|
assert "git" in brew_pkg.packages
|
||||||
|
assert "neovim" in brew_pkg.packages
|
||||||
|
|
||||||
|
def test_editors_parsing(self, sample_yaml_content, temp_dir):
|
||||||
|
"""Test parsing editors configuration."""
|
||||||
|
config_file = temp_dir / "config.yml"
|
||||||
|
config_file.write_text(sample_yaml_content)
|
||||||
|
|
||||||
|
loader = ConfigLoader(str(config_file))
|
||||||
|
config = loader.load()
|
||||||
|
|
||||||
|
assert "vscode" in config.editors
|
||||||
|
vscode_config = config.editors["vscode"]
|
||||||
|
assert "extensions" in vscode_config
|
||||||
|
assert len(vscode_config["extensions"]) == 1
|
||||||
|
|
||||||
|
def test_backup_config_parsing(self, sample_yaml_content, temp_dir):
|
||||||
|
"""Test parsing backup configuration."""
|
||||||
|
config_file = temp_dir / "config.yml"
|
||||||
|
config_file.write_text(sample_yaml_content)
|
||||||
|
|
||||||
|
loader = ConfigLoader(str(config_file))
|
||||||
|
config = loader.load()
|
||||||
|
|
||||||
|
assert config.backup.enabled == True
|
||||||
|
assert config.backup.directory == "~/.dev-env-sync-backups"
|
||||||
|
assert config.backup.timestamp_format == "%Y%m%d_%H%M%S"
|
||||||
|
|
||||||
|
def test_invalid_yaml(self, temp_dir):
|
||||||
|
"""Test handling of invalid YAML."""
|
||||||
|
config_file = temp_dir / "invalid.yml"
|
||||||
|
config_file.write_text("invalid: yaml: content: [")
|
||||||
|
|
||||||
|
loader = ConfigLoader(str(config_file))
|
||||||
|
|
||||||
|
with pytest.raises(ConfigParseError):
|
||||||
|
loader.load()
|
||||||
|
|
||||||
|
def test_nonexistent_file(self):
|
||||||
|
"""Test handling of nonexistent configuration file."""
|
||||||
|
loader = ConfigLoader("/nonexistent/path/config.yml")
|
||||||
|
|
||||||
|
with pytest.raises(ConfigParseError):
|
||||||
|
loader.load()
|
||||||
|
|
||||||
|
def test_create_default_config(self):
|
||||||
|
"""Test creating default configuration."""
|
||||||
|
config = ConfigLoader.create_default_config()
|
||||||
|
|
||||||
|
assert config is not None
|
||||||
|
assert config.version == "1.0"
|
||||||
|
assert config.name == "My Dev Environment"
|
||||||
|
assert len(config.dotfiles) > 0
|
||||||
|
assert len(config.packages) > 0
|
||||||
|
|
||||||
|
def test_config_to_dict(self, temp_dir):
|
||||||
|
"""Test converting config to dictionary."""
|
||||||
|
config_file = temp_dir / "config.yml"
|
||||||
|
config_file.write_text('version: "1.0"\nname: "Test"')
|
||||||
|
|
||||||
|
loader = ConfigLoader(str(config_file))
|
||||||
|
config = loader.load()
|
||||||
|
|
||||||
|
config_dict = config.to_dict()
|
||||||
|
|
||||||
|
assert isinstance(config_dict, dict)
|
||||||
|
assert config_dict["version"] == "1.0"
|
||||||
|
assert config_dict["name"] == "Test"
|
||||||
|
|
||||||
|
|
||||||
|
class TestConfigValidation:
|
||||||
|
"""Tests for configuration validation."""
|
||||||
|
|
||||||
|
def test_valid_config_schema(self, temp_dir):
|
||||||
|
"""Test that valid config matches schema."""
|
||||||
|
config_file = temp_dir / "valid.yml"
|
||||||
|
config_file.write_text('''
|
||||||
|
version: "1.0"
|
||||||
|
name: "Valid Test"
|
||||||
|
description: "Testing validation"
|
||||||
|
|
||||||
|
dotfiles:
|
||||||
|
test:
|
||||||
|
source: ./test
|
||||||
|
target: ~/.test
|
||||||
|
backup: true
|
||||||
|
|
||||||
|
backup:
|
||||||
|
enabled: true
|
||||||
|
directory: ~/.test-backups
|
||||||
|
''')
|
||||||
|
|
||||||
|
loader = ConfigLoader(str(config_file))
|
||||||
|
config = loader.load()
|
||||||
|
|
||||||
|
assert config.version == "1.0"
|
||||||
|
assert config.backup.enabled == True
|
||||||
|
|
||||||
|
def test_string_dotfile_shorthand(self, temp_dir):
|
||||||
|
"""Test string shorthand for dotfiles."""
|
||||||
|
config_file = temp_dir / "shorthand.yml"
|
||||||
|
config_file.write_text('''
|
||||||
|
version: "1.0"
|
||||||
|
|
||||||
|
dotfiles:
|
||||||
|
bashrc: ./bashrc
|
||||||
|
''')
|
||||||
|
|
||||||
|
loader = ConfigLoader(str(config_file))
|
||||||
|
config = loader.load()
|
||||||
|
|
||||||
|
assert "bashrc" in config.dotfiles
|
||||||
|
assert config.dotfiles["bashrc"].source == "./bashrc"
|
||||||
|
assert config.dotfiles["bashrc"].target == "~/.bashrc"
|
||||||
Reference in New Issue
Block a user