From 89595aa077d8b07f16baa744fcbcce05968ffe74 Mon Sep 17 00:00:00 2001 From: Gros Frumos Date: Thu, 19 Mar 2026 14:58:50 +0200 Subject: [PATCH] kin: auto-commit after pipeline --- tests/test_kin_docs_002_regression.py | 127 ++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 tests/test_kin_docs_002_regression.py diff --git a/tests/test_kin_docs_002_regression.py b/tests/test_kin_docs_002_regression.py new file mode 100644 index 0000000..c4015c0 --- /dev/null +++ b/tests/test_kin_docs_002_regression.py @@ -0,0 +1,127 @@ +"""Regression tests for KIN-DOCS-002 — Standardise all agent prompts. + +Acceptance criteria: +1. pytest green (checked by running this suite) +2. No file in agents/prompts/ contains the old '## Output format' section header +3. Every prompt file contains '## Return Format' +4. Every prompt file contains the full standard structure: + ## Working Mode, ## Focus On (or ## Focus), ## Quality Checks (or ## Quality), ## Return Format +""" + +from pathlib import Path + +import pytest + + +PROMPTS_DIR = Path(__file__).parent.parent / "agents" / "prompts" + + +def _prompt_files(): + return sorted(PROMPTS_DIR.glob("*.md")) + + +# --------------------------------------------------------------------------- +# AC-2: No legacy '## Output format' section +# --------------------------------------------------------------------------- + +class TestNoLegacyOutputFormatSection: + """Проверяет отсутствие устаревшей секции '## Output format' во всех промптах.""" + + def test_no_prompt_contains_old_output_format_header(self): + """Ни один файл agents/prompts/*.md не содержит '## Output format'.""" + files_with_old_header = [ + f.name + for f in _prompt_files() + if "## Output format" in f.read_text(encoding="utf-8") + ] + assert files_with_old_header == [], ( + f"Файлы с устаревшей секцией '## Output format': {files_with_old_header}" + ) + + def test_grep_output_format_is_empty(self): + """Эквивалент: grep -rl '## Output format' agents/prompts/ — пустой вывод.""" + matches = [ + str(f) + for f in _prompt_files() + if "## Output format" in f.read_text(encoding="utf-8") + ] + assert matches == [], ( + "grep -rl '## Output format' agents/prompts/ должен давать пустой вывод, " + f"но нашёл: {matches}" + ) + + +# --------------------------------------------------------------------------- +# AC-3: Every prompt contains '## Return Format' +# --------------------------------------------------------------------------- + +class TestAllPromptsContainReturnFormat: + """Проверяет наличие секции '## Return Format' во всех промптах.""" + + def test_return_format_count_equals_prompt_count(self): + """Число промптов с '## Return Format' равно общему числу промптов.""" + all_files = _prompt_files() + files_with_rf = [f for f in all_files if "## Return Format" in f.read_text(encoding="utf-8")] + assert len(files_with_rf) == len(all_files), ( + f"Промптов всего: {len(all_files)}, " + f"с '## Return Format': {len(files_with_rf)}. " + f"Без секции: {[f.name for f in all_files if f not in files_with_rf]}" + ) + + @pytest.mark.parametrize("prompt_file", [f.name for f in sorted(PROMPTS_DIR.glob("*.md"))]) + def test_each_prompt_has_return_format(self, prompt_file): + """Каждый промпт-файл содержит секцию '## Return Format'.""" + content = (PROMPTS_DIR / prompt_file).read_text(encoding="utf-8") + assert "## Return Format" in content, ( + f"{prompt_file} не содержит секцию '## Return Format'" + ) + + +# --------------------------------------------------------------------------- +# AC-4: Full standard structure in every prompt +# --------------------------------------------------------------------------- + +class TestAllPromptsContainStandardStructure: + """Проверяет наличие всех обязательных секций стандартного шаблона.""" + + REQUIRED_SECTIONS = [ + "## Working Mode", + "## Return Format", + ] + + @pytest.mark.parametrize("prompt_file", [f.name for f in sorted(PROMPTS_DIR.glob("*.md"))]) + def test_each_prompt_has_working_mode(self, prompt_file): + """Каждый промпт содержит секцию '## Working Mode'.""" + content = (PROMPTS_DIR / prompt_file).read_text(encoding="utf-8") + assert "## Working Mode" in content, ( + f"{prompt_file} не содержит секцию '## Working Mode'" + ) + + @pytest.mark.parametrize("prompt_file", [f.name for f in sorted(PROMPTS_DIR.glob("*.md"))]) + def test_return_format_comes_after_working_mode(self, prompt_file): + """Секция '## Return Format' идёт после '## Working Mode'.""" + content = (PROMPTS_DIR / prompt_file).read_text(encoding="utf-8") + wm_pos = content.find("## Working Mode") + rf_pos = content.find("## Return Format") + if wm_pos == -1 or rf_pos == -1: + pytest.skip(f"{prompt_file}: одна из секций отсутствует (покрывается другим тестом)") + assert rf_pos > wm_pos, ( + f"{prompt_file}: '## Return Format' (pos={rf_pos}) должна идти после " + f"'## Working Mode' (pos={wm_pos})" + ) + + +# --------------------------------------------------------------------------- +# Sanity: prompt count stays at 25 +# --------------------------------------------------------------------------- + +class TestPromptCount: + """Проверяет, что число промптов не изменилось неожиданно.""" + + def test_prompt_count_is_25(self): + """В agents/prompts/ ровно 25 файлов .md.""" + count = len(_prompt_files()) + assert count == 25, ( + f"Ожидалось 25 промптов, найдено {count}. " + "Если добавлен новый промпт — обнови этот тест." + )