Public Access
DEVX-10: feat: add tag verification, idempotency, and --verify mode to release script
Post-merge / detect-type (push) Successful in 9s
Post-merge / validate-commit-msg (push) Successful in 9s
Post-merge / configure-repo (push) Successful in 15s
Post-merge / release (push) Successful in 50s
Post-merge / vikunja (push) Successful in 17s
Post-merge / sync-wiki (push) Successful in 40s
Post-merge / badges (push) Successful in 1m0s
Post-merge / detect-type (push) Successful in 9s
Post-merge / validate-commit-msg (push) Successful in 9s
Post-merge / configure-repo (push) Successful in 15s
Post-merge / release (push) Successful in 50s
Post-merge / vikunja (push) Successful in 17s
Post-merge / sync-wiki (push) Successful in 40s
Post-merge / badges (push) Successful in 1m0s
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
"""Tests for devx.tools.generate_cliff_config."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import tomllib
|
||||
from pathlib import Path
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
from click.testing import CliRunner
|
||||
|
||||
from devx.tools.generate_cliff_config import main
|
||||
|
||||
|
||||
class TestGenerateCliffConfig:
|
||||
"""Tests for the generate_cliff_config tool."""
|
||||
|
||||
@pytest.fixture
|
||||
def runner(self) -> CliRunner:
|
||||
return CliRunner()
|
||||
|
||||
def test_generate_to_new_file(self, runner: CliRunner, tmp_path: Path) -> None:
|
||||
"""Generate cliff.toml to a new file."""
|
||||
output = tmp_path / "cliff.toml"
|
||||
result = runner.invoke(main, ["--prefix", "GRM", "--output", str(output)])
|
||||
assert result.exit_code == 0
|
||||
assert output.exists()
|
||||
content = output.read_text()
|
||||
assert "git-cliff configuration for GRM" in content
|
||||
assert 'pattern = "^GRM-\\\\d+:\\\\s+"' in content
|
||||
|
||||
def test_generate_with_default_prefix(self, runner: CliRunner, tmp_path: Path) -> None:
|
||||
"""Generate with default prefix (DEVX_TASK_PREFIX or 'DEVX')."""
|
||||
output = tmp_path / "cliff.toml"
|
||||
with patch("devx.tools.generate_cliff_config.TASK_PREFIX", "DEVX"):
|
||||
result = runner.invoke(main, ["--output", str(output)])
|
||||
assert result.exit_code == 0
|
||||
content = output.read_text()
|
||||
assert "git-cliff configuration for DEVX" in content
|
||||
|
||||
def test_existing_file_without_force(self, runner: CliRunner, tmp_path: Path) -> None:
|
||||
"""Refuse to overwrite existing file without --force."""
|
||||
output = tmp_path / "cliff.toml"
|
||||
output.write_text("# existing")
|
||||
result = runner.invoke(main, ["--prefix", "GRM", "--output", str(output)])
|
||||
assert result.exit_code != 0
|
||||
assert "already exists" in result.output
|
||||
assert output.read_text() == "# existing"
|
||||
|
||||
def test_existing_file_with_force(self, runner: CliRunner, tmp_path: Path) -> None:
|
||||
"""Overwrite existing file with --force."""
|
||||
output = tmp_path / "cliff.toml"
|
||||
output.write_text("# existing")
|
||||
result = runner.invoke(main, ["--prefix", "GRM", "--output", str(output), "--force"])
|
||||
assert result.exit_code == 0
|
||||
content = output.read_text()
|
||||
assert "git-cliff configuration for GRM" in content
|
||||
assert "# existing" not in content
|
||||
|
||||
def test_generated_config_is_valid_toml(self, runner: CliRunner, tmp_path: Path) -> None:
|
||||
"""Generated config must be valid TOML."""
|
||||
output = tmp_path / "cliff.toml"
|
||||
result = runner.invoke(main, ["--prefix", "GRM", "--output", str(output)])
|
||||
assert result.exit_code == 0
|
||||
with open(output, "rb") as f:
|
||||
data = tomllib.load(f)
|
||||
assert "changelog" in data
|
||||
assert "git" in data
|
||||
assert "bump" in data
|
||||
assert data["bump"]["initial_tag"] == "0.1.0"
|
||||
assert data["bump"]["features_always_bump_minor"] is True
|
||||
|
||||
def test_generated_config_has_correct_preprocessor(self, runner: CliRunner, tmp_path: Path) -> None:
|
||||
"""Preprocessor pattern must match the given prefix."""
|
||||
output = tmp_path / "cliff.toml"
|
||||
result = runner.invoke(main, ["--prefix", "INFRA", "--output", str(output)])
|
||||
assert result.exit_code == 0
|
||||
with open(output, "rb") as f:
|
||||
data = tomllib.load(f)
|
||||
preprocessors = data["git"]["commit_preprocessors"]
|
||||
assert len(preprocessors) == 1
|
||||
pattern = preprocessors[0]["pattern"]
|
||||
assert "INFRA" in pattern
|
||||
|
||||
def test_generated_config_has_commit_parsers(self, runner: CliRunner, tmp_path: Path) -> None:
|
||||
"""Generated config must have all standard commit parsers."""
|
||||
output = tmp_path / "cliff.toml"
|
||||
result = runner.invoke(main, ["--prefix", "GRM", "--output", str(output)])
|
||||
assert result.exit_code == 0
|
||||
with open(output, "rb") as f:
|
||||
data = tomllib.load(f)
|
||||
parsers = data["git"]["commit_parsers"]
|
||||
# Should have feat, fix, perf, refactor, doc, test, style, chore, ci, release, security, revert, catch-all
|
||||
messages = [p["message"] for p in parsers if "message" in p]
|
||||
assert "^feat" in messages
|
||||
assert "^fix" in messages
|
||||
assert "^perf" in messages
|
||||
assert "^refactor" in messages
|
||||
assert "^release:" in messages
|
||||
assert "^revert" in messages
|
||||
assert ".*" in messages # catch-all
|
||||
|
||||
def test_default_output_path(self, runner: CliRunner, tmp_path: Path) -> None:
|
||||
"""Default output path is cliff.toml in current directory."""
|
||||
output = tmp_path / "cliff.toml"
|
||||
# Change to tmp_path so default cliff.toml is created there
|
||||
import os
|
||||
|
||||
old_cwd = os.getcwd()
|
||||
os.chdir(tmp_path)
|
||||
try:
|
||||
result = runner.invoke(main, ["--prefix", "GRM"])
|
||||
assert result.exit_code == 0
|
||||
assert output.exists()
|
||||
finally:
|
||||
os.chdir(old_cwd)
|
||||
|
||||
def test_success_message(self, runner: CliRunner, tmp_path: Path) -> None:
|
||||
"""Success message includes file and prefix."""
|
||||
output = tmp_path / "cliff.toml"
|
||||
result = runner.invoke(main, ["--prefix", "GRM", "--output", str(output)])
|
||||
assert result.exit_code == 0
|
||||
assert "Generated" in result.output
|
||||
assert "GRM" in result.output
|
||||
Reference in New Issue
Block a user