diff --git a/app/local_commit_message_generator/tests/test_config.py b/app/local_commit_message_generator/tests/test_config.py new file mode 100644 index 0000000..12273e4 --- /dev/null +++ b/app/local_commit_message_generator/tests/test_config.py @@ -0,0 +1,143 @@ +"""Tests for configuration module.""" + +import os +import tempfile +from pathlib import Path +from unittest.mock import patch + +import pytest + +from src.config import ( + DEFAULT_CONFIG, + DEFAULT_TYPE_RULES, + get_config_path, + load_config, + save_config, + get_type_rules, + get_template, + ConfigError, +) + + +class TestGetConfigPath: + """Tests for get_config_path function.""" + + def test_returns_home_config(self): + """Test that config path is in home directory.""" + with patch("src.config.Path.home") as mock_home: + mock_home.return_value = Path("/home/testuser") + result = get_config_path() + assert result == Path("/home/testuser/.local_commit_gen.toml") + + +class TestLoadConfig: + """Tests for load_config function.""" + + def test_loads_default_config_when_no_file(self): + """Test that default config is loaded when file doesn't exist.""" + with tempfile.TemporaryDirectory() as tmpdir: + config_path = Path(tmpdir) / "nonexistent.toml" + result = load_config(config_path) + assert result == DEFAULT_CONFIG + + def test_loads_custom_config(self): + """Test loading custom configuration.""" + with tempfile.TemporaryDirectory() as tmpdir: + config_path = Path(tmpdir) / "config.toml" + custom_config = """ +template = "{type}: {description}" + +[scopes] +src = "source" +""" + with open(config_path, "w") as f: + f.write(custom_config) + + result = load_config(config_path) + assert result["template"] == "{type}: {description}" + assert result["scopes"]["src"] == "source" + + def test_merges_custom_type_rules(self): + """Test that custom type rules are merged with defaults.""" + with tempfile.TemporaryDirectory() as tmpdir: + config_path = Path(tmpdir) / "config.toml" + custom_config = """ +[type_rules] +feat = ["custom/feat/"] +""" + with open(config_path, "w") as f: + f.write(custom_config) + + result = load_config(config_path) + assert "feat" in result["type_rules"] + assert "custom/feat/" in result["type_rules"]["feat"] + assert result["type_rules"]["fix"] == DEFAULT_TYPE_RULES["fix"] + + def test_invalid_toml_raises_error(self): + """Test that invalid TOML raises ConfigError.""" + with tempfile.TemporaryDirectory() as tmpdir: + config_path = Path(tmpdir) / "invalid.toml" + with open(config_path, "w") as f: + f.write("invalid = toml = syntax") + + with pytest.raises(ConfigError): + load_config(config_path) + + +class TestSaveConfig: + """Tests for save_config function.""" + + def test_saves_config_to_file(self): + """Test saving configuration to file.""" + with tempfile.TemporaryDirectory() as tmpdir: + config_path = Path(tmpdir) / "config.toml" + config = {"test": "value", "nested": {"key": "val"}} + + save_config(config, config_path) + + assert config_path.exists() + loaded = load_config(config_path) + assert loaded["test"] == "value" + + def test_overwrites_existing_config(self): + """Test overwriting existing configuration.""" + with tempfile.TemporaryDirectory() as tmpdir: + config_path = Path(tmpdir) / "config.toml" + save_config({"old": "value"}, config_path) + save_config({"new": "value"}, config_path) + + loaded = load_config(config_path) + assert loaded["new"] == "value" + + +class TestGetTypeRules: + """Tests for get_type_rules function.""" + + def test_returns_rules_from_config(self): + """Test returning type rules from config.""" + custom_rules = {"feat": ["custom/"]} + config = {"type_rules": custom_rules} + result = get_type_rules(config) + assert result["feat"] == ["custom/"] + + def test_returns_default_when_no_config(self): + """Test returning default rules when no config provided.""" + result = get_type_rules() + assert "feat" in result + assert "fix" in result + assert "docs" in result + + +class TestGetTemplate: + """Tests for get_template function.""" + + def test_returns_template_from_config(self): + """Test returning template from config.""" + config = {"template": "custom: {description}"} + result = get_template(config) + assert result == "custom: {description}" + + def test_returns_default_when_no_config(self): + """Test returning default template when no config provided.""" + result = get_template() + assert result == DEFAULT_CONFIG["template"]