feat(system): test(seedgo): cover all 117 untested functions per TDPLAN-0003 — 826 tests passing, 100% function coverage

Co-Authored-By: @devpulse <devpulse@aipass>
This commit is contained in:
AIOSAI
2026-04-25 23:49:18 -07:00
co-authored by @devpulse
parent 2e826c2211
commit 2f1969c972
6 changed files with 5530 additions and 0 deletions
@@ -0,0 +1,900 @@
"""Tests for seedgo checker sub-functions -- batch 6 (architecture, cli, cli_flags, documentation)."""
# =================== META ====================
# Name: test_checkers_batch6.py
# Description: Unit tests for checker sub-functions in architecture, cli, cli_flags, documentation
# Version: 1.0.0
# Created: 2026-04-25
# Modified: 2026-04-25
# =============================================
from typing import List
import pytest
from unittest.mock import MagicMock
def _lines(text: str) -> List[str]:
"""Split text into lines, widening LiteralString to str for pyright."""
return text.split("\n")
# ---------------------------------------------------------------------------
# Fixtures
# ---------------------------------------------------------------------------
@pytest.fixture(autouse=True)
def _mock_infrastructure(monkeypatch):
"""Mock heavy infrastructure imports for standards checkers."""
import sys
mock_logger = MagicMock()
mock_json_handler = MagicMock()
mock_json_handler.log_operation = MagicMock(return_value=True)
# -- prax ---------------------------------------------------------------
prax_mod = MagicMock()
prax_mod.logger = mock_logger
monkeypatch.setitem(sys.modules, "aipass.prax", prax_mod)
# -- seedgo json handler ------------------------------------------------
json_pkg = MagicMock()
json_pkg.json_handler = mock_json_handler
monkeypatch.setitem(sys.modules, "aipass.seedgo.apps.handlers.json", json_pkg)
json_mod = MagicMock()
json_mod.log_operation = mock_json_handler.log_operation
monkeypatch.setitem(
sys.modules,
"aipass.seedgo.apps.handlers.json.json_handler",
json_mod,
)
# -- bypass handler (used by architecture_check) ------------------------
bypass_pkg = MagicMock()
bypass_ignore = MagicMock()
bypass_ignore.get_template_ignore_patterns = MagicMock(return_value=[])
bypass_pkg.ignore_handler = bypass_ignore
monkeypatch.setitem(sys.modules, "aipass.seedgo.apps.handlers.bypass", bypass_pkg)
monkeypatch.setitem(
sys.modules,
"aipass.seedgo.apps.handlers.bypass.ignore_handler",
bypass_ignore,
)
# Force re-imports so checkers pick up fresh mocks
for mod_name in [
"aipass.seedgo.apps.handlers.aipass_standards.architecture_check",
"aipass.seedgo.apps.handlers.aipass_standards.cli_check",
"aipass.seedgo.apps.handlers.aipass_standards.cli_flags_check",
"aipass.seedgo.apps.handlers.aipass_standards.documentation_check",
]:
monkeypatch.delitem(sys.modules, mod_name, raising=False)
# ===========================================================================
# 1. architecture_check sub-functions
# ===========================================================================
# -- check_layer_location ---------------------------------------------------
class TestCheckLayerLocation:
"""Tests for check_layer_location."""
def test_entry_point_passes(self):
"""Entry point path is recognised as the entry-point layer."""
from aipass.seedgo.apps.handlers.aipass_standards.architecture_check import (
check_layer_location,
)
result = check_layer_location("/branch/apps/branch.py", True, False, False)
assert result["passed"] is True
assert "Entry point" in result["message"]
def test_module_layer_passes(self):
"""Module path is recognised as the module layer."""
from aipass.seedgo.apps.handlers.aipass_standards.architecture_check import (
check_layer_location,
)
result = check_layer_location("/branch/apps/modules/foo.py", False, True, False)
assert result["passed"] is True
assert "Module layer" in result["message"]
def test_handler_layer_passes(self):
"""Handler path is recognised as the handler layer."""
from aipass.seedgo.apps.handlers.aipass_standards.architecture_check import (
check_layer_location,
)
result = check_layer_location("/branch/apps/handlers/json/j.py", False, False, True)
assert result["passed"] is True
assert "Handler layer" in result["message"]
def test_outside_3_layer_fails(self):
"""Path outside the 3-layer structure fails."""
from aipass.seedgo.apps.handlers.aipass_standards.architecture_check import (
check_layer_location,
)
result = check_layer_location("/branch/random/foo.py", False, False, False)
assert result["passed"] is False
assert "not in standard 3-layer" in result["message"]
# -- check_file_size (architecture) -----------------------------------------
class TestArchCheckFileSize:
"""Tests for architecture_check.check_file_size."""
def test_small_file_passes(self):
"""Under 300 lines is perfect."""
from aipass.seedgo.apps.handlers.aipass_standards.architecture_check import (
check_file_size,
)
lines: list[str] = ["x"] * 100
result = check_file_size(lines, "small.py")
assert result["passed"] is True
assert "perfect" in result["message"]
def test_medium_file_passes(self):
"""300-500 lines is good."""
from aipass.seedgo.apps.handlers.aipass_standards.architecture_check import (
check_file_size,
)
lines: list[str] = ["x"] * 350
result = check_file_size(lines, "medium.py")
assert result["passed"] is True
assert "good" in result["message"]
def test_heavy_file_passes(self):
"""500-700 lines is acceptable but heavy."""
from aipass.seedgo.apps.handlers.aipass_standards.architecture_check import (
check_file_size,
)
lines: list[str] = ["x"] * 600
result = check_file_size(lines, "heavy.py")
assert result["passed"] is True
assert "getting heavy" in result["message"]
def test_oversized_file_fails(self):
"""700+ lines fails the size check."""
from aipass.seedgo.apps.handlers.aipass_standards.architecture_check import (
check_file_size,
)
lines: list[str] = ["x"] * 750
result = check_file_size(lines, "huge.py")
assert result["passed"] is False
assert "consider splitting" in result["message"]
# -- check_handler_independence (architecture) --------------------------------
class TestArchHandlerIndependence:
"""Tests for architecture_check.check_handler_independence."""
def test_clean_handler_passes(self):
"""Handler without parent module imports passes."""
from aipass.seedgo.apps.handlers.aipass_standards.architecture_check import (
check_handler_independence,
)
lines: list[str] = [
"from aipass.prax import logger",
"from aipass.cli.apps.modules import display",
"",
"def do_work():",
" return True",
]
result = check_handler_independence(lines, "/seedgo/apps/handlers/json/j.py")
assert result is not None
assert result["passed"] is True
def test_parent_module_import_fails(self):
"""Handler importing from its parent branch module fails."""
from aipass.seedgo.apps.handlers.aipass_standards.architecture_check import (
check_handler_independence,
)
lines: list[str] = [
"from seedgo.apps.modules.audit import run_audit",
"",
"def do_work():",
" return True",
]
result = check_handler_independence(lines, "/seedgo/apps/handlers/json/j.py")
assert result is not None
assert result["passed"] is False
assert "parent module" in result["message"]
def test_allowed_service_imports_pass(self):
"""Prax and CLI service imports are allowed in handlers."""
from aipass.seedgo.apps.handlers.aipass_standards.architecture_check import (
check_handler_independence,
)
lines: list[str] = [
"from prax.apps.modules.logger import info",
"from cli.apps.modules.display import header",
]
result = check_handler_independence(lines, "/seedgo/apps/handlers/json/j.py")
assert result is not None
assert result["passed"] is True
def test_import_in_docstring_ignored(self):
"""Imports inside docstrings are not flagged."""
from aipass.seedgo.apps.handlers.aipass_standards.architecture_check import (
check_handler_independence,
)
lines: list[str] = [
'"""',
"from seedgo.apps.modules.audit import run_audit",
'"""',
"def do_work():",
" return True",
]
result = check_handler_independence(lines, "/seedgo/apps/handlers/json/j.py")
assert result is not None
assert result["passed"] is True
# -- check_domain_organization -----------------------------------------------
class TestCheckDomainOrganization:
"""Tests for check_domain_organization."""
def test_domain_based_passes(self):
"""Handler in a domain-named folder passes."""
from aipass.seedgo.apps.handlers.aipass_standards.architecture_check import (
check_domain_organization,
)
result = check_domain_organization("/branch/apps/handlers/json/json_handler.py")
assert result is not None
assert result["passed"] is True
assert "json" in result["message"]
def test_technical_name_fails(self):
"""Handler in a technical-named folder (utils) fails."""
from aipass.seedgo.apps.handlers.aipass_standards.architecture_check import (
check_domain_organization,
)
result = check_domain_organization("/branch/apps/handlers/utils/helper.py")
assert result is not None
assert result["passed"] is False
assert "Technical organization" in result["message"]
def test_helpers_name_fails(self):
"""Handler in a helpers/ folder fails."""
from aipass.seedgo.apps.handlers.aipass_standards.architecture_check import (
check_domain_organization,
)
result = check_domain_organization("/branch/apps/handlers/helpers/tool.py")
assert result is not None
assert result["passed"] is False
def test_no_handler_domain_detected(self):
"""Path ending at handlers/ with no subdirectory fails detection."""
from aipass.seedgo.apps.handlers.aipass_standards.architecture_check import (
check_domain_organization,
)
result = check_domain_organization("/branch/apps/handlers")
assert result is not None
assert result["passed"] is False
assert "Could not detect" in result["message"]
# -- check_template_baseline -------------------------------------------------
class TestCheckTemplateBaseline:
"""Tests for check_template_baseline."""
def test_no_branch_path_detected(self):
"""Path without apps/ cannot resolve a branch."""
from aipass.seedgo.apps.handlers.aipass_standards.architecture_check import (
check_template_baseline,
)
result = check_template_baseline("/random/file.py")
assert len(result) >= 1
assert result[0]["passed"] is False
assert "Could not detect branch path" in result[0]["message"]
def test_missing_citizen_class(self, tmp_path):
"""Branch without passport.json fails the citizen_class check."""
from aipass.seedgo.apps.handlers.aipass_standards.architecture_check import (
check_template_baseline,
)
apps_dir = tmp_path / "mybranch" / "apps"
apps_dir.mkdir(parents=True)
entry = apps_dir / "mybranch.py"
entry.write_text('"""Entry."""\n', encoding="utf-8")
result = check_template_baseline(str(entry))
assert len(result) >= 1
assert result[0]["passed"] is False
assert "citizen_class" in result[0]["message"]
# ===========================================================================
# 2. cli_check sub-functions
# ===========================================================================
# -- check_handler_separation ------------------------------------------------
class TestCheckHandlerSeparation:
"""Tests for check_handler_separation."""
def test_clean_handler_passes(self):
"""Handler with no console output passes."""
from aipass.seedgo.apps.handlers.aipass_standards.cli_check import (
check_handler_separation,
)
content = "def compute():\n return 42\n"
result = check_handler_separation(content)
assert result["passed"] is True
assert "No console output" in result["message"]
def test_console_print_fails(self):
"""Handler with console.print() fails."""
from aipass.seedgo.apps.handlers.aipass_standards.cli_check import (
check_handler_separation,
)
content = "def show():\n console.print('hello')\n"
result = check_handler_separation(content)
assert result["passed"] is False
assert "console.print()" in result["message"]
def test_bare_print_fails(self):
"""Handler with bare print() fails."""
from aipass.seedgo.apps.handlers.aipass_standards.cli_check import (
check_handler_separation,
)
content = "def show():\n print('hello')\n"
result = check_handler_separation(content)
assert result["passed"] is False
assert "print()" in result["message"]
def test_cli_import_fails(self):
"""Handler importing CLI services fails separation check."""
from aipass.seedgo.apps.handlers.aipass_standards.cli_check import (
check_handler_separation,
)
content = "from aipass.cli.apps.modules.display import header\ndef show():\n pass\n"
result = check_handler_separation(content)
assert result["passed"] is False
assert "CLI services" in result["message"]
def test_print_in_main_block_ignored(self):
"""Print inside if __name__ block is allowed."""
from aipass.seedgo.apps.handlers.aipass_standards.cli_check import (
check_handler_separation,
)
content = "def compute():\n return 42\nif __name__ == '__main__':\n print('test output')\n"
result = check_handler_separation(content)
assert result["passed"] is True
def test_console_print_in_string_ignored(self):
"""Console.print inside a string literal is not flagged."""
from aipass.seedgo.apps.handlers.aipass_standards.cli_check import (
check_handler_separation,
)
content = "msg = 'use console.print() for output'\n"
result = check_handler_separation(content)
assert result["passed"] is True
# -- check_cli_imports -------------------------------------------------------
class TestCheckCliImports:
"""Tests for check_cli_imports."""
def test_has_cli_imports_passes(self):
"""Module with CLI service imports passes."""
from aipass.seedgo.apps.handlers.aipass_standards.cli_check import (
check_cli_imports,
)
content = "from aipass.cli.apps.modules.display import header\n"
result = check_cli_imports(content, "/seedgo/apps/modules/audit.py")
assert result is not None
assert result["passed"] is True
def test_cli_branch_exempt(self):
"""CLI branch itself is exempt from this check."""
from aipass.seedgo.apps.handlers.aipass_standards.cli_check import (
check_cli_imports,
)
content = "from .display import header\n"
result = check_cli_imports(content, "/cli/apps/modules/something.py")
assert result is not None
assert result["passed"] is True
assert "CLI branch exempt" in result["message"]
def test_output_without_cli_imports_fails(self):
"""Module with output but no CLI imports fails."""
from aipass.seedgo.apps.handlers.aipass_standards.cli_check import (
check_cli_imports,
)
content = "print('hello world')\n"
result = check_cli_imports(content, "/seedgo/apps/modules/audit.py")
assert result is not None
assert result["passed"] is False
assert "missing CLI service imports" in result["message"]
def test_no_output_at_all_passes(self):
"""Module with no output at all passes."""
from aipass.seedgo.apps.handlers.aipass_standards.cli_check import (
check_cli_imports,
)
content = "def compute():\n return 42\n"
result = check_cli_imports(content, "/seedgo/apps/modules/audit.py")
assert result is not None
assert result["passed"] is True
assert "No CLI output needed" in result["message"]
def test_shortcut_import_passes(self):
"""Shortcut import via cli __init__ passes."""
from aipass.seedgo.apps.handlers.aipass_standards.cli_check import (
check_cli_imports,
)
content = "from aipass.cli import header\n"
result = check_cli_imports(content, "/seedgo/apps/modules/audit.py")
assert result is not None
assert result["passed"] is True
# -- check_print_usage -------------------------------------------------------
class TestCheckPrintUsage:
"""Tests for check_print_usage."""
def test_console_print_passes(self):
"""File using console.print passes."""
from aipass.seedgo.apps.handlers.aipass_standards.cli_check import (
check_print_usage,
)
content = "console.print('hello')\n"
lines = _lines(content)
result = check_print_usage(content, lines, "/module.py")
assert result is not None
assert result["passed"] is True
def test_bare_print_fails(self):
"""Bare print() statement fails."""
from aipass.seedgo.apps.handlers.aipass_standards.cli_check import (
check_print_usage,
)
content = "print('hello')\n"
lines = _lines(content)
result = check_print_usage(content, lines, "/module.py")
assert result is not None
assert result["passed"] is False
assert "print() statements" in result["message"]
def test_parser_print_help_fails(self):
"""parser.print_help() usage fails."""
from aipass.seedgo.apps.handlers.aipass_standards.cli_check import (
check_print_usage,
)
content = "parser.print_help()\n"
lines = _lines(content)
result = check_print_usage(content, lines, "/module.py")
assert result is not None
assert result["passed"] is False
assert "parser.print_help()" in result["message"]
def test_sys_stdout_write_fails(self):
"""sys.stdout.write() usage fails."""
from aipass.seedgo.apps.handlers.aipass_standards.cli_check import (
check_print_usage,
)
content = "import sys\nsys.stdout.write('hello')\n"
lines = _lines(content)
result = check_print_usage(content, lines, "/module.py")
assert result is not None
assert result["passed"] is False
assert "sys.stdout" in result["message"]
def test_print_in_main_block_ignored(self):
"""Print inside if __name__ block returns None (no violation)."""
from aipass.seedgo.apps.handlers.aipass_standards.cli_check import (
check_print_usage,
)
content = "if __name__ == '__main__':\n print('test')\n"
lines = _lines(content)
result = check_print_usage(content, lines, "/module.py")
assert result is None
def test_no_output_returns_none(self):
"""File with no output returns None."""
from aipass.seedgo.apps.handlers.aipass_standards.cli_check import (
check_print_usage,
)
content = "x = 42\n"
lines = _lines(content)
result = check_print_usage(content, lines, "/module.py")
assert result is None
def test_bypass_rule_skips_line(self):
"""Bypassed print line is not flagged."""
from aipass.seedgo.apps.handlers.aipass_standards.cli_check import (
check_print_usage,
)
content = "print('hello')\n"
lines = _lines(content)
bypass = [{"standard": "cli", "file": "module.py", "lines": [1]}]
result = check_print_usage(content, lines, "/module.py", bypass_rules=bypass)
assert result is None
# -- check_help_flag ---------------------------------------------------------
class TestCheckHelpFlag:
"""Tests for check_help_flag."""
def test_argparse_with_help_passes(self):
"""Module with argparse and help/h flags passes."""
from aipass.seedgo.apps.handlers.aipass_standards.cli_check import (
check_help_flag,
)
content = "import argparse\nparser = argparse.ArgumentParser()\n--help\n-h\n"
result = check_help_flag(content)
assert result is not None
assert result["passed"] is True
def test_print_help_function_passes(self):
"""Module with def print_help passes."""
from aipass.seedgo.apps.handlers.aipass_standards.cli_check import (
check_help_flag,
)
content = "def print_help():\n pass\n"
result = check_help_flag(content)
assert result is not None
assert result["passed"] is True
def test_executable_without_help_fails(self):
"""Executable module without --help fails."""
from aipass.seedgo.apps.handlers.aipass_standards.cli_check import (
check_help_flag,
)
content = "if __name__ == '__main__':\n main()\n"
result = check_help_flag(content)
assert result is not None
assert result["passed"] is False
assert "--help flag not implemented" in result["message"]
def test_non_executable_returns_none(self):
"""Non-executable module returns None (not applicable)."""
from aipass.seedgo.apps.handlers.aipass_standards.cli_check import (
check_help_flag,
)
content = "def compute():\n return 42\n"
result = check_help_flag(content)
assert result is None
# -- check_duplicate_display_functions ----------------------------------------
class TestCheckDuplicateDisplayFunctions:
"""Tests for check_duplicate_display_functions."""
def test_no_duplicates_passes(self):
"""Module without CLI display function duplicates passes."""
from aipass.seedgo.apps.handlers.aipass_standards.cli_check import (
check_duplicate_display_functions,
)
content = "def compute():\n return 42\n"
result = check_duplicate_display_functions(content, "/seedgo/apps/modules/audit.py")
assert result is not None
assert result["passed"] is True
def test_duplicate_header_fails(self):
"""Module defining its own header() fails."""
from aipass.seedgo.apps.handlers.aipass_standards.cli_check import (
check_duplicate_display_functions,
)
content = "def header(title):\n print(title)\n"
result = check_duplicate_display_functions(content, "/seedgo/apps/modules/audit.py")
assert result is not None
assert result["passed"] is False
assert "header" in result["message"]
def test_duplicate_error_and_warning_fails(self):
"""Module defining error() and warning() fails."""
from aipass.seedgo.apps.handlers.aipass_standards.cli_check import (
check_duplicate_display_functions,
)
content = "def error(msg):\n pass\ndef warning(msg):\n pass\n"
result = check_duplicate_display_functions(content, "/seedgo/apps/modules/audit.py")
assert result is not None
assert result["passed"] is False
assert "error" in result["message"]
def test_cli_branch_exempt(self):
"""CLI branch is exempt (it defines these functions)."""
from aipass.seedgo.apps.handlers.aipass_standards.cli_check import (
check_duplicate_display_functions,
)
content = "def header(title):\n print(title)\n"
result = check_duplicate_display_functions(content, "/cli/apps/modules/display.py")
assert result is None
def test_prax_logger_exempt(self):
"""Prax logger module is exempt (it is the logging system)."""
from aipass.seedgo.apps.handlers.aipass_standards.cli_check import (
check_duplicate_display_functions,
)
content = "def error(msg):\n pass\n"
result = check_duplicate_display_functions(content, "/prax/apps/modules/logger/log.py")
assert result is None
# ===========================================================================
# 3. cli_flags_check sub-functions
# ===========================================================================
# -- check_version_flag ------------------------------------------------------
class TestCheckVersionFlag:
"""Tests for check_version_flag."""
def test_version_flag_found_passes(self):
"""Entry point with '--version' string passes."""
from aipass.seedgo.apps.handlers.aipass_standards.cli_flags_check import (
check_version_flag,
)
lines: list[str] = [
"def main():",
" if '--version' in args:",
" print(VERSION)",
]
result = check_version_flag(lines, "/branch/apps/branch.py", None)
assert result["passed"] is True
assert "version flag" in result["message"].lower()
def test_short_version_flag_passes(self):
"""Entry point with '-V' string passes."""
from aipass.seedgo.apps.handlers.aipass_standards.cli_flags_check import (
check_version_flag,
)
lines: list[str] = [
"def main():",
" if '-V' in args:",
" print(VERSION)",
]
result = check_version_flag(lines, "/branch/apps/branch.py", None)
assert result["passed"] is True
def test_no_version_flag_fails(self):
"""Entry point without any version flag handling fails."""
from aipass.seedgo.apps.handlers.aipass_standards.cli_flags_check import (
check_version_flag,
)
lines: list[str] = [
"def main():",
" print('hello')",
]
result = check_version_flag(lines, "/branch/apps/branch.py", None)
assert result["passed"] is False
assert "missing --version" in result["message"].lower()
def test_version_in_docstring_ignored(self):
"""Version flag mentioned only in a docstring does not count."""
from aipass.seedgo.apps.handlers.aipass_standards.cli_flags_check import (
check_version_flag,
)
lines: list[str] = [
'"""',
"Supports --version flag",
'"""',
"def main():",
" pass",
]
result = check_version_flag(lines, "/branch/apps/branch.py", None)
assert result["passed"] is False
def test_bypassed_passes(self):
"""Bypassed entry point passes regardless."""
from aipass.seedgo.apps.handlers.aipass_standards.cli_flags_check import (
check_version_flag,
)
lines: list[str] = ["def main():", " pass"]
bypass = [{"standard": "cli_flags", "file": "branch.py"}]
result = check_version_flag(lines, "/branch/apps/branch.py", bypass)
assert result["passed"] is True
assert "Bypassed" in result["message"]
# ===========================================================================
# 4. documentation_check sub-functions
# ===========================================================================
# -- check_module_docstring --------------------------------------------------
class TestCheckModuleDocstring:
"""Tests for check_module_docstring."""
def test_docstring_present_passes(self):
"""File with a module-level docstring passes."""
from aipass.seedgo.apps.handlers.aipass_standards.documentation_check import (
check_module_docstring,
)
lines: list[str] = [
"# META block",
"",
'"""Module docstring."""',
"",
"def foo():",
]
result = check_module_docstring(lines)
assert result["passed"] is True
def test_docstring_missing_fails(self):
"""File without a docstring in the first 30 lines fails."""
from aipass.seedgo.apps.handlers.aipass_standards.documentation_check import (
check_module_docstring,
)
lines: list[str] = [
"# Just a comment",
"import os",
"import sys",
"def foo():",
" pass",
] + ["# more code"] * 30
result = check_module_docstring(lines)
assert result["passed"] is False
assert "Missing module-level docstring" in result["message"]
def test_single_quote_docstring_passes(self):
"""Single-quote triple-quote docstring is accepted."""
from aipass.seedgo.apps.handlers.aipass_standards.documentation_check import (
check_module_docstring,
)
lines: list[str] = ["'''Module docstring.'''", "", "def foo():"]
result = check_module_docstring(lines)
assert result["passed"] is True
def test_docstring_after_meta_block_passes(self):
"""Docstring after META header block is accepted."""
from aipass.seedgo.apps.handlers.aipass_standards.documentation_check import (
check_module_docstring,
)
lines: list[str] = [
"# ========= META =========",
"# Name: foo.py",
"# ========================",
"",
'"""',
"Multi-line docstring.",
'"""',
]
result = check_module_docstring(lines)
assert result["passed"] is True
# -- check_function_docstrings -----------------------------------------------
class TestCheckFunctionDocstrings:
"""Tests for check_function_docstrings."""
def test_all_public_documented_passes(self):
"""All public functions with docstrings passes."""
from aipass.seedgo.apps.handlers.aipass_standards.documentation_check import (
check_function_docstrings,
)
content = 'def foo():\n """Does foo."""\n pass\ndef bar():\n """Does bar."""\n pass\n'
lines = _lines(content)
result = check_function_docstrings(content, lines)
assert result["passed"] is True
assert "2 public functions" in result["message"]
def test_missing_docstring_fails(self):
"""Public function without docstring fails."""
from aipass.seedgo.apps.handlers.aipass_standards.documentation_check import (
check_function_docstrings,
)
content = "def foo():\n pass\n"
lines = _lines(content)
result = check_function_docstrings(content, lines)
assert result["passed"] is False
assert "foo" in result["message"]
def test_private_functions_skipped(self):
"""Private functions (starting with _) are not checked."""
from aipass.seedgo.apps.handlers.aipass_standards.documentation_check import (
check_function_docstrings,
)
content = "def _private_helper():\n pass\n"
lines = _lines(content)
result = check_function_docstrings(content, lines)
assert result["passed"] is True
assert "No public functions" in result["message"]
def test_no_functions_passes(self):
"""File with no functions passes vacuously."""
from aipass.seedgo.apps.handlers.aipass_standards.documentation_check import (
check_function_docstrings,
)
content = "x = 42\ny = 43\n"
lines = _lines(content)
result = check_function_docstrings(content, lines)
assert result["passed"] is True
def test_multiline_signature_docstring_found(self):
"""Docstring after a multi-line function signature is detected."""
from aipass.seedgo.apps.handlers.aipass_standards.documentation_check import (
check_function_docstrings,
)
content = (
'def compute(\n arg1: str,\n arg2: int,\n) -> bool:\n """Compute something."""\n return True\n'
)
lines = _lines(content)
result = check_function_docstrings(content, lines)
assert result["passed"] is True
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,963 @@
"""Tests for seedgo checker handlers — batch 8 (7 checkers)."""
# =================== META ====================
# Name: test_checkers_batch8.py
# Description: Unit tests for handlers, log_handler, log_level, log_structure, meta, naming, permission_flags
# Version: 1.0.0
# Created: 2026-04-25
# Modified: 2026-04-25
# =============================================
import pytest
from typing import List
from unittest.mock import MagicMock
# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------
def _lines(text: str) -> List[str]:
"""Split text into lines, widening LiteralString to str for pyright."""
return text.split("\n")
# ---------------------------------------------------------------------------
# Fixtures
# ---------------------------------------------------------------------------
@pytest.fixture(autouse=True)
def _mock_infrastructure(monkeypatch):
"""Mock heavy infrastructure imports for standards checkers."""
import sys
mock_logger = MagicMock()
mock_json_handler = MagicMock()
mock_json_handler.log_operation = MagicMock(return_value=True)
# -- prax ---------------------------------------------------------------
prax_mod = MagicMock()
prax_mod.logger = mock_logger
monkeypatch.setitem(sys.modules, "aipass.prax", prax_mod)
# -- seedgo json handler ------------------------------------------------
json_pkg = MagicMock()
json_pkg.json_handler = mock_json_handler
monkeypatch.setitem(sys.modules, "aipass.seedgo.apps.handlers.json", json_pkg)
json_mod = MagicMock()
json_mod.log_operation = mock_json_handler.log_operation
monkeypatch.setitem(sys.modules, "aipass.seedgo.apps.handlers.json.json_handler", json_mod)
# -- bypass handler -----------------------------------------------------
bypass_pkg = MagicMock()
bypass_ignore = MagicMock()
bypass_ignore.get_template_ignore_patterns = MagicMock(return_value=[])
bypass_pkg.ignore_handler = bypass_ignore
monkeypatch.setitem(sys.modules, "aipass.seedgo.apps.handlers.bypass", bypass_pkg)
monkeypatch.setitem(
sys.modules,
"aipass.seedgo.apps.handlers.bypass.ignore_handler",
bypass_ignore,
)
# Force re-imports so checkers pick up fresh mocks
for mod_name in [
"aipass.seedgo.apps.handlers.aipass_standards.handlers_check",
"aipass.seedgo.apps.handlers.aipass_standards.log_handler_check",
"aipass.seedgo.apps.handlers.aipass_standards.log_level_check",
"aipass.seedgo.apps.handlers.aipass_standards.log_structure_check",
"aipass.seedgo.apps.handlers.aipass_standards.meta_check",
"aipass.seedgo.apps.handlers.aipass_standards.naming_check",
"aipass.seedgo.apps.handlers.aipass_standards.permission_flags_check",
]:
monkeypatch.delitem(sys.modules, mod_name, raising=False)
# ===========================================================================
# 1. handlers_check -- check_handler_independence
# ===========================================================================
def test_handler_independence_clean(tmp_path):
"""Handler with no cross-handler imports passes."""
content = (
'"""Clean handler."""\n'
"from aipass.seedgo.apps.handlers.json import json_handler\n"
"\ndef do_work():\n return True\n"
)
handler_path = str(tmp_path / "apps" / "handlers" / "audit" / "clean.py")
from aipass.seedgo.apps.handlers.aipass_standards.handlers_check import (
check_handler_independence,
)
result = check_handler_independence(content, _lines(content), handler_path)
assert result["passed"] is True
def test_handler_independence_cross_import(tmp_path):
"""Handler importing from another handler package fails."""
content = (
'"""Cross handler import."""\n'
"from aipass.seedgo.apps.handlers.error import error_handler\n"
"\ndef do_work():\n return True\n"
)
handler_path = str(tmp_path / "apps" / "handlers" / "audit" / "cross.py")
from aipass.seedgo.apps.handlers.aipass_standards.handlers_check import (
check_handler_independence,
)
result = check_handler_independence(content, _lines(content), handler_path)
assert result["passed"] is False
assert "Cross-handler imports" in result["message"]
def test_handler_independence_same_package(tmp_path):
"""Handler importing from same package passes."""
content = (
'"""Same package import."""\n'
"from aipass.seedgo.apps.handlers.audit import audit_helper\n"
"\ndef do_work():\n return True\n"
)
handler_path = str(tmp_path / "apps" / "handlers" / "audit" / "same.py")
from aipass.seedgo.apps.handlers.aipass_standards.handlers_check import (
check_handler_independence,
)
result = check_handler_independence(content, _lines(content), handler_path)
assert result["passed"] is True
# ===========================================================================
# 2. handlers_check -- check_auto_detection
# ===========================================================================
def test_auto_detection_not_needed():
"""No module_name parameter means auto-detection is not needed (returns None)."""
content = "def do_work(file_path):\n return True\n"
from aipass.seedgo.apps.handlers.aipass_standards.handlers_check import (
check_auto_detection,
)
result = check_auto_detection(content)
assert result is None
def test_auto_detection_present():
"""Handler with module_name and inspect.stack() passes."""
content = "import inspect\ndef do_work(module_name=None):\n frame = inspect.stack()\n return True\n"
from aipass.seedgo.apps.handlers.aipass_standards.handlers_check import (
check_auto_detection,
)
result = check_auto_detection(content)
assert result is not None
assert result["passed"] is True
def test_auto_detection_missing():
"""Handler with module_name but no inspect.stack() fails."""
content = "def do_work(module_name=None):\n return True\n"
from aipass.seedgo.apps.handlers.aipass_standards.handlers_check import (
check_auto_detection,
)
result = check_auto_detection(content)
assert result is not None
assert result["passed"] is False
assert "missing auto-detection" in result["message"]
def test_auto_detection_with_get_caller():
"""Handler with _get_caller_module_name passes auto-detection."""
content = "def _get_caller_module_name():\n pass\ndef do_work(module_name=None):\n return True\n"
from aipass.seedgo.apps.handlers.aipass_standards.handlers_check import (
check_auto_detection,
)
result = check_auto_detection(content)
assert result is not None
assert result["passed"] is True
# ===========================================================================
# 3. handlers_check -- check_no_orchestration
# ===========================================================================
def test_no_orchestration_clean():
"""Handler with no module imports passes."""
content = '"""Clean handler."""\n\ndef do_work():\n return True\n'
from aipass.seedgo.apps.handlers.aipass_standards.handlers_check import (
check_no_orchestration,
)
result = check_no_orchestration(content, _lines(content))
assert result is not None
assert result["passed"] is True
def test_no_orchestration_module_import():
"""Handler importing from apps.modules fails."""
content = (
'"""Bad handler."""\nfrom aipass.seedgo.apps.modules import audit_module\n\ndef do_work():\n return True\n'
)
from aipass.seedgo.apps.handlers.aipass_standards.handlers_check import (
check_no_orchestration,
)
result = check_no_orchestration(content, _lines(content))
assert result is not None
assert result["passed"] is False
assert "orchestration" in result["message"]
def test_no_orchestration_in_docstring():
"""Module import inside docstring is not flagged."""
content = (
'"""\nExample: from aipass.seedgo.apps.modules import audit_module\n"""\n\ndef do_work():\n return True\n'
)
from aipass.seedgo.apps.handlers.aipass_standards.handlers_check import (
check_no_orchestration,
)
result = check_no_orchestration(content, _lines(content))
assert result is not None
assert result["passed"] is True
# ===========================================================================
# 4. log_handler_check -- check_no_raw_file_handler
# ===========================================================================
def test_no_raw_file_handler_clean():
"""File without logging.FileHandler passes."""
lines: List[str] = [
'"""Clean module."""',
"import logging",
"logger = logging.getLogger(__name__)",
"",
]
from aipass.seedgo.apps.handlers.aipass_standards.log_handler_check import (
check_no_raw_file_handler,
)
result = check_no_raw_file_handler(lines, "/fake/path.py")
assert result["passed"] is True
def test_no_raw_file_handler_violation():
"""File with logging.FileHandler fails."""
# seedgo:bypass standard=log_handler reason="test data for checker validation"
lines: List[str] = [
'"""Bad module."""',
"import logging",
'handler = logging.FileHandler("app.log")',
"",
]
from aipass.seedgo.apps.handlers.aipass_standards.log_handler_check import (
check_no_raw_file_handler,
)
result = check_no_raw_file_handler(lines, "/fake/path.py")
assert result["passed"] is False
assert "FileHandler" in result["message"]
# ===========================================================================
# 5. log_handler_check -- check_no_raw_stream_handler
# ===========================================================================
def test_no_raw_stream_handler_no_file_logging():
"""No file-based logging means stream handler check not applicable."""
lines: List[str] = [
"import logging",
"logger = logging.getLogger(__name__)",
"",
]
content = "\n".join(lines)
from aipass.seedgo.apps.handlers.aipass_standards.log_handler_check import (
check_no_raw_stream_handler,
)
result = check_no_raw_stream_handler(lines, "/fake/path.py", content)
assert result["passed"] is True
assert "not applicable" in result["message"]
def test_no_raw_stream_handler_violation():
"""StreamHandler with file logging is a violation."""
# seedgo:bypass standard=log_handler reason="test data for checker validation"
lines: List[str] = [
"import logging",
'handler = logging.FileHandler("app.log")',
"stream = logging.StreamHandler()",
"",
]
content = "\n".join(lines)
from aipass.seedgo.apps.handlers.aipass_standards.log_handler_check import (
check_no_raw_stream_handler,
)
result = check_no_raw_stream_handler(lines, "/fake/path.py", content)
assert result["passed"] is False
assert "StreamHandler" in result["message"]
def test_no_raw_stream_handler_clean():
"""File logging present but no StreamHandler passes."""
# seedgo:bypass standard=log_handler reason="test data for checker validation"
lines: List[str] = [
"import logging",
'handler = logging.FileHandler("app.log")',
"",
]
content = "\n".join(lines)
from aipass.seedgo.apps.handlers.aipass_standards.log_handler_check import (
check_no_raw_stream_handler,
)
result = check_no_raw_stream_handler(lines, "/fake/path.py", content)
assert result["passed"] is True
# ===========================================================================
# 6. log_level_check -- check_error_not_user_input
# ===========================================================================
def test_error_not_user_input_clean():
"""ERROR used for system failures passes."""
lines: List[str] = [
'"""Module."""',
'logger.error("System crash: %s", error)',
"",
]
from aipass.seedgo.apps.handlers.aipass_standards.log_level_check import (
check_error_not_user_input,
)
result = check_error_not_user_input(lines, "/fake/path.py")
assert result["passed"] is True
def test_error_not_user_input_violation():
"""ERROR used for user-input pattern fails."""
# seedgo:bypass standard=log_level reason="test data for checker validation"
lines: List[str] = [
'"""Module."""',
'logger.error("Unknown command: %s", cmd)',
"",
]
from aipass.seedgo.apps.handlers.aipass_standards.log_level_check import (
check_error_not_user_input,
)
result = check_error_not_user_input(lines, "/fake/path.py")
assert result["passed"] is False
assert "user input" in result["message"]
def test_error_not_user_input_in_docstring():
"""ERROR pattern inside a docstring is ignored."""
# seedgo:bypass standard=log_level reason="test data for checker validation"
lines: List[str] = [
'"""',
'logger.error("Unknown command: %s", cmd)',
'"""',
"pass",
"",
]
from aipass.seedgo.apps.handlers.aipass_standards.log_level_check import (
check_error_not_user_input,
)
result = check_error_not_user_input(lines, "/fake/path.py")
assert result["passed"] is True
# ===========================================================================
# 7. log_level_check -- check_command_routing_level
# ===========================================================================
def test_command_routing_level_no_routing():
"""File without command routing returns None."""
content = "def do_work():\n pass\n"
from aipass.seedgo.apps.handlers.aipass_standards.log_level_check import (
check_command_routing_level,
)
result = check_command_routing_level(content, _lines(content), "/fake/path.py")
assert result is None
def test_command_routing_level_clean():
"""Command routing with proper WARNING level passes."""
content = 'def route_command(cmd):\n logger.warning("Unknown command: %s", cmd)\n'
from aipass.seedgo.apps.handlers.aipass_standards.log_level_check import (
check_command_routing_level,
)
result = check_command_routing_level(content, _lines(content), "/fake/path.py")
assert result is not None
assert result["passed"] is True
def test_command_routing_level_violation():
"""Command routing with ERROR for user-input pattern fails."""
# seedgo:bypass standard=log_level reason="test data for checker validation"
content = 'def route_command(cmd):\n logger.error("Unknown command: %s", cmd)\n'
from aipass.seedgo.apps.handlers.aipass_standards.log_level_check import (
check_command_routing_level,
)
result = check_command_routing_level(content, _lines(content), "/fake/path.py")
assert result is not None
assert result["passed"] is False
assert "ERROR" in result["message"] or "WARNING" in result["message"]
# ===========================================================================
# 8. log_structure_check -- check_branch_post
# ===========================================================================
def test_check_branch_post_no_logs(tmp_path):
"""Branch with no logs returns empty violations."""
branch = tmp_path / "mybranch"
branch.mkdir()
from aipass.seedgo.apps.handlers.aipass_standards.log_structure_check import (
check_branch_post,
)
violations, scores = check_branch_post(str(branch))
assert violations == []
assert scores == []
def test_check_branch_post_with_system_logs(tmp_path):
"""Branch with local logs and system logs passes."""
branch = tmp_path / "mybranch"
branch.mkdir()
logs_dir = branch / "logs"
logs_dir.mkdir()
(logs_dir / "app.log").write_text("log line", encoding="utf-8")
# Create repo-level registry and system_logs
registry = tmp_path / "AIPASS_REGISTRY.json"
registry.write_text("{}", encoding="utf-8")
sys_logs = tmp_path / "system_logs"
sys_logs.mkdir()
(sys_logs / "mybranch_system.log").write_text("system log", encoding="utf-8")
from aipass.seedgo.apps.handlers.aipass_standards.log_structure_check import (
check_branch_post,
)
violations, scores = check_branch_post(str(branch))
assert 100 in scores
def test_check_branch_post_local_no_system(tmp_path):
"""Branch with local logs but no system logs is flagged."""
branch = tmp_path / "mybranch"
branch.mkdir()
logs_dir = branch / "logs"
logs_dir.mkdir()
(logs_dir / "app.log").write_text("log line", encoding="utf-8")
# Create repo-level registry and system_logs, but no branch-specific system log
registry = tmp_path / "AIPASS_REGISTRY.json"
registry.write_text("{}", encoding="utf-8")
sys_logs = tmp_path / "system_logs"
sys_logs.mkdir()
from aipass.seedgo.apps.handlers.aipass_standards.log_structure_check import (
check_branch_post,
)
violations, scores = check_branch_post(str(branch))
assert 50 in scores
assert len(violations) == 1
assert "prax dispatch" in violations[0]["issues"][0]
# ===========================================================================
# 9. meta_check -- check_meta_presence
# ===========================================================================
def test_meta_presence_valid():
"""Content with both header and footer markers passes."""
content = (
"# =================== AIPass ====================\n"
"# Name: test.py\n"
"# Description: Test file\n"
"# Version: 1.0.0\n"
"# Created: 2026-01-01\n"
"# Modified: 2026-01-01\n"
"# =============================================\n"
)
from aipass.seedgo.apps.handlers.aipass_standards.meta_check import (
check_meta_presence,
)
result = check_meta_presence(content)
assert result["passed"] is True
def test_meta_presence_missing_header():
"""Content without header marker fails."""
content = "# Name: test.py\n# =============================================\n"
from aipass.seedgo.apps.handlers.aipass_standards.meta_check import (
check_meta_presence,
)
result = check_meta_presence(content)
assert result["passed"] is False
assert "header" in result["message"]
def test_meta_presence_legacy_header():
"""Content with legacy META header passes."""
content = (
"# =================== META ====================\n"
"# Name: test.py\n"
"# =============================================\n"
)
from aipass.seedgo.apps.handlers.aipass_standards.meta_check import (
check_meta_presence,
)
result = check_meta_presence(content)
assert result["passed"] is True
# ===========================================================================
# 10. meta_check -- check_meta_placement
# ===========================================================================
def test_meta_placement_at_top():
"""META block at line 1 passes."""
content = "# =================== AIPass ====================\nrest of file\n"
from aipass.seedgo.apps.handlers.aipass_standards.meta_check import (
check_meta_placement,
)
result = check_meta_placement(content)
assert result["passed"] is True
def test_meta_placement_not_at_top():
"""META block not at line 1 fails."""
content = '"""Docstring first."""\n# =================== AIPass ====================\n'
from aipass.seedgo.apps.handlers.aipass_standards.meta_check import (
check_meta_placement,
)
result = check_meta_placement(content)
assert result["passed"] is False
assert "first line" in result["message"]
# ===========================================================================
# 11. meta_check -- check_required_fields
# ===========================================================================
def test_required_fields_all_present():
"""All required META fields present passes."""
content = (
"# =================== AIPass ====================\n"
"# Name: test.py\n"
"# Description: Test file\n"
"# Version: 1.0.0\n"
"# Created: 2026-01-01\n"
"# Modified: 2026-01-01\n"
"# =============================================\n"
)
from aipass.seedgo.apps.handlers.aipass_standards.meta_check import (
check_required_fields,
)
results = check_required_fields(content, "test.py")
assert all(r["passed"] for r in results)
def test_required_fields_missing_version():
"""Missing Version field fails."""
content = (
"# =================== AIPass ====================\n"
"# Name: test.py\n"
"# Description: Test file\n"
"# Created: 2026-01-01\n"
"# Modified: 2026-01-01\n"
"# =============================================\n"
)
from aipass.seedgo.apps.handlers.aipass_standards.meta_check import (
check_required_fields,
)
results = check_required_fields(content, "test.py")
version_result = [r for r in results if "Version" in r["name"]]
assert len(version_result) == 1
assert version_result[0]["passed"] is False
def test_required_fields_wrong_name():
"""Name field not matching filename fails."""
content = (
"# =================== AIPass ====================\n"
"# Name: wrong_name.py\n"
"# Description: Test file\n"
"# Version: 1.0.0\n"
"# Created: 2026-01-01\n"
"# Modified: 2026-01-01\n"
"# =============================================\n"
)
from aipass.seedgo.apps.handlers.aipass_standards.meta_check import (
check_required_fields,
)
results = check_required_fields(content, "test.py")
name_result = [r for r in results if "Name" in r["name"]]
assert len(name_result) == 1
assert name_result[0]["passed"] is False
assert "wrong_name.py" in name_result[0]["message"]
# ===========================================================================
# 12. naming_check -- check_file_naming
# ===========================================================================
def test_file_naming_snake_case(tmp_path):
"""Snake_case filename passes."""
f = tmp_path / "good_module.py"
f.write_text("pass", encoding="utf-8")
from aipass.seedgo.apps.handlers.aipass_standards.naming_check import (
check_file_naming,
)
result = check_file_naming(str(f), f)
assert result["passed"] is True
def test_file_naming_bad_case(tmp_path):
"""Uppercase filename fails."""
f = tmp_path / "BadModule.py"
f.write_text("pass", encoding="utf-8")
from aipass.seedgo.apps.handlers.aipass_standards.naming_check import (
check_file_naming,
)
result = check_file_naming(str(f), f)
assert result["passed"] is False
assert "invalid characters" in result["message"]
def test_file_naming_redundant_prefix(tmp_path):
"""Filename with redundant parent dir prefix fails."""
parent = tmp_path / "audit"
parent.mkdir()
f = parent / "audit_ops.py"
f.write_text("pass", encoding="utf-8")
from aipass.seedgo.apps.handlers.aipass_standards.naming_check import (
check_file_naming,
)
result = check_file_naming(str(f), f)
assert result["passed"] is False
assert "redundant prefix" in result["message"]
def test_file_naming_init(tmp_path):
"""__init__.py passes (Python-reserved)."""
f = tmp_path / "__init__.py"
f.write_text("", encoding="utf-8")
from aipass.seedgo.apps.handlers.aipass_standards.naming_check import (
check_file_naming,
)
result = check_file_naming(str(f), f)
assert result["passed"] is True
# ===========================================================================
# 13. naming_check -- check_function_naming
# ===========================================================================
def test_function_naming_all_snake():
"""All snake_case functions pass."""
content = "def do_work():\n pass\n\ndef get_data():\n pass\n"
from aipass.seedgo.apps.handlers.aipass_standards.naming_check import (
check_function_naming,
)
result = check_function_naming(content)
assert result is not None
assert result["passed"] is True
def test_function_naming_camel_case():
"""CamelCase function fails."""
content = "def DoWork():\n pass\n"
from aipass.seedgo.apps.handlers.aipass_standards.naming_check import (
check_function_naming,
)
result = check_function_naming(content)
assert result is not None
assert result["passed"] is False
assert "DoWork" in result["message"]
def test_function_naming_no_functions():
"""No functions returns None."""
content = "X = 42\n"
from aipass.seedgo.apps.handlers.aipass_standards.naming_check import (
check_function_naming,
)
result = check_function_naming(content)
assert result is None
def test_function_naming_dunder_skipped():
"""Dunder methods are skipped from violation checks but still counted."""
content = "class Foo:\n def __init__(self):\n pass\n"
from aipass.seedgo.apps.handlers.aipass_standards.naming_check import (
check_function_naming,
)
result = check_function_naming(content)
# __init__ is found but skipped from violation checks, so it passes
assert result is not None
assert result["passed"] is True
# ===========================================================================
# 14. naming_check -- check_constant_naming
# ===========================================================================
def test_constant_naming_upper():
"""UPPER_CASE constants pass."""
content = 'MY_CONST = "hello"\nANOTHER = 42\n'
from aipass.seedgo.apps.handlers.aipass_standards.naming_check import (
check_constant_naming,
)
result = check_constant_naming(content)
assert result is not None
assert result["passed"] is True
def test_constant_naming_lowercase():
"""Lowercase constants fail."""
content = 'my_const = "hello"\n'
from aipass.seedgo.apps.handlers.aipass_standards.naming_check import (
check_constant_naming,
)
result = check_constant_naming(content)
assert result is not None
assert result["passed"] is False
assert "my_const" in result["message"]
def test_constant_naming_function_call_ignored():
"""Constants assigned via function call are ignored."""
content = "logger = logging.getLogger(__name__)\n"
from aipass.seedgo.apps.handlers.aipass_standards.naming_check import (
check_constant_naming,
)
result = check_constant_naming(content)
# Function call assignment is skipped, no constants to check
assert result is None
# ===========================================================================
# 15. naming_check -- check_class_naming
# ===========================================================================
def test_class_naming_pascal():
"""PascalCase class passes."""
content = "class MyClass:\n pass\n"
from aipass.seedgo.apps.handlers.aipass_standards.naming_check import (
check_class_naming,
)
result = check_class_naming(content)
assert result is not None
assert result["passed"] is True
def test_class_naming_snake():
"""snake_case class fails."""
content = "class my_class:\n pass\n"
from aipass.seedgo.apps.handlers.aipass_standards.naming_check import (
check_class_naming,
)
result = check_class_naming(content)
assert result is not None
assert result["passed"] is False
assert "my_class" in result["message"]
def test_class_naming_no_classes():
"""No classes returns None."""
content = "def do_work():\n pass\n"
from aipass.seedgo.apps.handlers.aipass_standards.naming_check import (
check_class_naming,
)
result = check_class_naming(content)
assert result is None
# ===========================================================================
# 16. permission_flags_check -- check_no_dangerous_flags
# ===========================================================================
def test_no_dangerous_flags_clean():
"""File with only approved permission flags passes."""
lines: List[str] = [
'"""Clean module."""',
'"--permission-mode bypassPermissions"',
"",
]
from aipass.seedgo.apps.handlers.aipass_standards.permission_flags_check import (
check_no_dangerous_flags,
)
result = check_no_dangerous_flags(lines, "/fake/path.py")
assert result["passed"] is True
def test_no_dangerous_flags_violation():
"""File with prohibited permission bypass flag fails."""
# seedgo:bypass standard=permission_flags reason="test data for checker validation"
lines: List[str] = [
'"""Module."""',
'cmd = "--dangerously-skip-permissions"',
"",
]
from aipass.seedgo.apps.handlers.aipass_standards.permission_flags_check import (
check_no_dangerous_flags,
)
result = check_no_dangerous_flags(lines, "/fake/path.py")
assert result["passed"] is False
assert "Dangerous" in result["message"]
def test_no_dangerous_flags_in_docstring():
"""Prohibited flag inside docstring is ignored."""
# seedgo:bypass standard=permission_flags reason="test data for checker validation"
lines: List[str] = [
'"""',
"Use --dangerously-skip-permissions for testing",
'"""',
"pass",
"",
]
from aipass.seedgo.apps.handlers.aipass_standards.permission_flags_check import (
check_no_dangerous_flags,
)
result = check_no_dangerous_flags(lines, "/fake/path.py")
assert result["passed"] is True
def test_no_dangerous_flags_skip_permissions():
"""File with --skip-permissions fails."""
# seedgo:bypass standard=permission_flags reason="test data for checker validation"
lines: List[str] = [
'"""Module."""',
'cmd = "--skip-permissions"',
"",
]
from aipass.seedgo.apps.handlers.aipass_standards.permission_flags_check import (
check_no_dangerous_flags,
)
result = check_no_dangerous_flags(lines, "/fake/path.py")
assert result["passed"] is False
def test_no_dangerous_flags_bypass_rule():
"""Prohibited flag bypassed by rule passes."""
# seedgo:bypass standard=permission_flags reason="test data for checker validation"
lines: List[str] = [
'"""Module."""',
'cmd = "--dangerously-skip-permissions"',
"",
]
bypass_rules = [{"standard": "permission_flags", "file": "/fake/path.py"}]
from aipass.seedgo.apps.handlers.aipass_standards.permission_flags_check import (
check_no_dangerous_flags,
)
result = check_no_dangerous_flags(lines, "/fake/path.py", bypass_rules=bypass_rules)
assert result["passed"] is True
@@ -0,0 +1,710 @@
"""Tests for seedgo checker handlers — batch 9 (readme_check, trigger_check)."""
# =================== META ====================
# Name: test_checkers_batch9.py
# Description: Unit tests for readme_check and trigger_check
# Version: 1.0.0
# Created: 2026-04-25
# Modified: 2026-04-25
# =============================================
import pytest
from typing import List
from unittest.mock import MagicMock
# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------
def _lines(text: str) -> List[str]:
"""Split text into lines, widening LiteralString to str for pyright."""
return text.split("\n")
# ---------------------------------------------------------------------------
# Fixtures
# ---------------------------------------------------------------------------
@pytest.fixture(autouse=True)
def _mock_infrastructure(monkeypatch):
"""Mock heavy infrastructure imports for standards checkers."""
import sys
mock_logger = MagicMock()
mock_json_handler = MagicMock()
mock_json_handler.log_operation = MagicMock(return_value=True)
# -- prax ---------------------------------------------------------------
prax_mod = MagicMock()
prax_mod.logger = mock_logger
monkeypatch.setitem(sys.modules, "aipass.prax", prax_mod)
# -- seedgo json handler ------------------------------------------------
json_pkg = MagicMock()
json_pkg.json_handler = mock_json_handler
monkeypatch.setitem(sys.modules, "aipass.seedgo.apps.handlers.json", json_pkg)
json_mod = MagicMock()
json_mod.log_operation = mock_json_handler.log_operation
monkeypatch.setitem(sys.modules, "aipass.seedgo.apps.handlers.json.json_handler", json_mod)
# -- bypass handler -----------------------------------------------------
bypass_pkg = MagicMock()
bypass_ignore = MagicMock()
bypass_ignore.get_template_ignore_patterns = MagicMock(return_value=[])
bypass_pkg.ignore_handler = bypass_ignore
monkeypatch.setitem(sys.modules, "aipass.seedgo.apps.handlers.bypass", bypass_pkg)
monkeypatch.setitem(
sys.modules,
"aipass.seedgo.apps.handlers.bypass.ignore_handler",
bypass_ignore,
)
# Force re-imports so checkers pick up fresh mocks
for mod_name in [
"aipass.seedgo.apps.handlers.aipass_standards.readme_check",
"aipass.seedgo.apps.handlers.aipass_standards.trigger_check",
]:
monkeypatch.delitem(sys.modules, mod_name, raising=False)
# ===========================================================================
# 1. readme_check -- check_readme_exists
# ===========================================================================
def test_readme_exists_present(tmp_path):
"""README.md exists passes."""
readme = tmp_path / "README.md"
readme.write_text("# Branch\n", encoding="utf-8")
from aipass.seedgo.apps.handlers.aipass_standards.readme_check import (
check_readme_exists,
)
result = check_readme_exists(readme)
assert result["passed"] is True
def test_readme_exists_missing(tmp_path):
"""README.md missing fails."""
readme = tmp_path / "README.md"
from aipass.seedgo.apps.handlers.aipass_standards.readme_check import (
check_readme_exists,
)
result = check_readme_exists(readme)
assert result["passed"] is False
# ===========================================================================
# 2. readme_check -- check_required_sections
# ===========================================================================
def test_required_sections_all_present():
"""README with all required section groups passes."""
lines: List[str] = [
"# Branch",
"",
"## Architecture",
"Some content here.",
"",
"## Commands",
"- cmd1",
"",
"## Integration Points",
"Details here.",
]
from aipass.seedgo.apps.handlers.aipass_standards.readme_check import (
check_required_sections,
)
result = check_required_sections(lines, "/fake/apps/entry.py")
assert result["passed"] is True
def test_required_sections_missing_commands():
"""README missing Commands/Usage section fails."""
lines: List[str] = [
"# Branch",
"",
"## Architecture",
"Some content.",
"",
"## Depends On",
"Details.",
]
from aipass.seedgo.apps.handlers.aipass_standards.readme_check import (
check_required_sections,
)
result = check_required_sections(lines, "/fake/apps/entry.py")
assert result["passed"] is False
assert "Commands/Usage" in result["message"]
def test_required_sections_alternate_names():
"""README with alternate section names (Usage, Directory Structure, Provides To) passes."""
lines: List[str] = [
"# Branch",
"",
"## Directory Structure",
"Tree here.",
"",
"## Usage",
"- usage1",
"",
"## Provides To",
"Other branches.",
]
from aipass.seedgo.apps.handlers.aipass_standards.readme_check import (
check_required_sections,
)
result = check_required_sections(lines, "/fake/apps/entry.py")
assert result["passed"] is True
# ===========================================================================
# 3. readme_check -- check_last_updated_freshness
# ===========================================================================
def test_last_updated_freshness_present(tmp_path):
"""README with recent Last Updated passes."""
from datetime import datetime
today = datetime.now().strftime("%Y-%m-%d")
lines: List[str] = [
"# Branch",
f"*Last Updated: {today}*",
"",
]
branch_root = tmp_path / "mybranch"
branch_root.mkdir()
apps_dir = branch_root / "apps"
apps_dir.mkdir()
(apps_dir / "entry.py").write_text("pass", encoding="utf-8")
from aipass.seedgo.apps.handlers.aipass_standards.readme_check import (
check_last_updated_freshness,
)
result = check_last_updated_freshness(lines, branch_root, "/fake/apps/entry.py")
assert result["passed"] is True
def test_last_updated_freshness_missing():
"""README without Last Updated date fails."""
lines: List[str] = [
"# Branch",
"No date here.",
"",
]
from aipass.seedgo.apps.handlers.aipass_standards.readme_check import (
check_last_updated_freshness,
)
# branch_root doesn't matter since date is missing
from pathlib import Path
result = check_last_updated_freshness(lines, Path("/nonexistent"), "/fake/apps/entry.py")
assert result["passed"] is False
assert "Last Updated" in result["message"]
# ===========================================================================
# 4. readme_check -- check_directory_tree
# ===========================================================================
def test_directory_tree_accurate(tmp_path):
"""Directory tree listing valid directories passes."""
branch_root = tmp_path / "mybranch"
apps_dir = branch_root / "apps"
modules_dir = apps_dir / "modules"
modules_dir.mkdir(parents=True)
lines: List[str] = [
"# Branch",
"",
"## Architecture",
"",
"```",
"mybranch/",
" apps/",
" modules/",
"```",
]
from aipass.seedgo.apps.handlers.aipass_standards.readme_check import (
check_directory_tree,
)
result = check_directory_tree(lines, branch_root, "/fake/apps/entry.py")
assert result["passed"] is True
def test_directory_tree_no_tree_section():
"""README without a tree block passes (optional)."""
lines: List[str] = [
"# Branch",
"",
"## Other Section",
"Some content.",
]
from aipass.seedgo.apps.handlers.aipass_standards.readme_check import (
check_directory_tree,
)
from pathlib import Path
result = check_directory_tree(lines, Path("/nonexistent"), "/fake/apps/entry.py")
assert result["passed"] is True
assert "optional" in result["message"].lower() or "No directory" in result["message"]
# ===========================================================================
# 5. readme_check -- check_module_list
# ===========================================================================
def test_module_list_all_mentioned(tmp_path):
"""All modules in apps/modules/ mentioned in README passes."""
branch_root = tmp_path / "mybranch"
modules_dir = branch_root / "apps" / "modules"
modules_dir.mkdir(parents=True)
(modules_dir / "audit.py").write_text("pass", encoding="utf-8")
(modules_dir / "report.py").write_text("pass", encoding="utf-8")
(modules_dir / "__init__.py").write_text("", encoding="utf-8")
lines: List[str] = [
"# Branch",
"This branch has audit and report modules.",
]
from aipass.seedgo.apps.handlers.aipass_standards.readme_check import (
check_module_list,
)
result = check_module_list(lines, branch_root, "/fake/apps/entry.py")
assert result["passed"] is True
def test_module_list_missing_module(tmp_path):
"""Module not mentioned in README fails."""
branch_root = tmp_path / "mybranch"
modules_dir = branch_root / "apps" / "modules"
modules_dir.mkdir(parents=True)
(modules_dir / "secret_module.py").write_text("pass", encoding="utf-8")
lines: List[str] = [
"# Branch",
"No modules mentioned here.",
]
from aipass.seedgo.apps.handlers.aipass_standards.readme_check import (
check_module_list,
)
result = check_module_list(lines, branch_root, "/fake/apps/entry.py")
assert result["passed"] is False
assert "secret_module" in result["message"]
def test_module_list_no_modules_dir(tmp_path):
"""No apps/modules/ directory passes (skipped)."""
branch_root = tmp_path / "mybranch"
branch_root.mkdir()
lines: List[str] = ["# Branch"]
from aipass.seedgo.apps.handlers.aipass_standards.readme_check import (
check_module_list,
)
result = check_module_list(lines, branch_root, "/fake/apps/entry.py")
assert result["passed"] is True
# ===========================================================================
# 6. readme_check -- check_command_list
# ===========================================================================
def test_command_list_present():
"""Commands section with content passes."""
lines: List[str] = [
"# Branch",
"",
"## Commands",
"- `audit` - Run audit",
"- `report` - Generate report",
"",
"## Other",
]
from aipass.seedgo.apps.handlers.aipass_standards.readme_check import (
check_command_list,
)
result = check_command_list(lines, "/fake/apps/entry.py")
assert result["passed"] is True
assert "2 content lines" in result["message"]
def test_command_list_empty():
"""Commands section with no content fails."""
lines: List[str] = [
"# Branch",
"",
"## Commands",
"",
"## Other Section",
]
from aipass.seedgo.apps.handlers.aipass_standards.readme_check import (
check_command_list,
)
result = check_command_list(lines, "/fake/apps/entry.py")
assert result["passed"] is False
assert "empty" in result["message"].lower()
def test_command_list_missing():
"""No Commands section at all fails."""
lines: List[str] = [
"# Branch",
"",
"## Architecture",
"Content here.",
]
from aipass.seedgo.apps.handlers.aipass_standards.readme_check import (
check_command_list,
)
result = check_command_list(lines, "/fake/apps/entry.py")
assert result["passed"] is False
assert "No Commands" in result["message"]
# ===========================================================================
# 7. trigger_check -- is_handler_layer
# ===========================================================================
def test_is_handler_layer_true():
"""File in handlers/ directory is handler layer."""
from aipass.seedgo.apps.handlers.aipass_standards.trigger_check import (
is_handler_layer,
)
assert is_handler_layer("/src/aipass/seedgo/apps/handlers/audit/ops.py") is True
def test_is_handler_layer_false():
"""File in modules/ directory is not handler layer."""
from aipass.seedgo.apps.handlers.aipass_standards.trigger_check import (
is_handler_layer,
)
assert is_handler_layer("/src/aipass/seedgo/apps/modules/audit.py") is False
# ===========================================================================
# 8. trigger_check -- is_trigger_handler
# ===========================================================================
def test_is_trigger_handler_true():
"""File in trigger handlers/events/ is a trigger handler."""
from aipass.seedgo.apps.handlers.aipass_standards.trigger_check import (
is_trigger_handler,
)
assert is_trigger_handler("/apps/handlers/events/trigger_on_audit.py") is True
def test_is_trigger_handler_false():
"""File not in trigger handlers/events/ is not a trigger handler."""
from aipass.seedgo.apps.handlers.aipass_standards.trigger_check import (
is_trigger_handler,
)
assert is_trigger_handler("/apps/modules/audit.py") is False
# ===========================================================================
# 9. trigger_check -- check_no_logger_imports
# ===========================================================================
def test_no_logger_imports_clean():
"""Handler without prax logger imports passes."""
content = "def handle_event(**kwargs):\n pass\n"
lines = _lines(content)
from aipass.seedgo.apps.handlers.aipass_standards.trigger_check import (
check_no_logger_imports,
)
result = check_no_logger_imports(content, lines, "/fake/handler.py")
assert result["passed"] is True
def test_no_logger_imports_violation():
"""Handler importing prax logger fails."""
content = "from prax import logger\n\ndef handle_event(**kwargs):\n pass\n"
lines = _lines(content)
from aipass.seedgo.apps.handlers.aipass_standards.trigger_check import (
check_no_logger_imports,
)
result = check_no_logger_imports(content, lines, "/fake/handler.py")
assert result["passed"] is False
assert "recursion" in result["message"]
# ===========================================================================
# 10. trigger_check -- check_no_print_statements
# ===========================================================================
def test_no_print_statements_clean():
"""Handler without print statements passes."""
content = "def handle_event(**kwargs):\n return True\n"
lines = _lines(content)
from aipass.seedgo.apps.handlers.aipass_standards.trigger_check import (
check_no_print_statements,
)
result = check_no_print_statements(content, lines, "/fake/handler.py")
assert result["passed"] is True
def test_no_print_statements_violation():
"""Handler with print() fails."""
content = 'def handle_event(**kwargs):\n print("debug")\n'
lines = _lines(content)
from aipass.seedgo.apps.handlers.aipass_standards.trigger_check import (
check_no_print_statements,
)
result = check_no_print_statements(content, lines, "/fake/handler.py")
assert result["passed"] is False
assert "print()" in result["message"]
def test_no_print_in_main_block_ok():
"""print() inside __main__ block is allowed."""
content = 'def handle_event(**kwargs):\n return True\n\nif __name__ == "__main__":\n print("testing")\n'
lines = _lines(content)
from aipass.seedgo.apps.handlers.aipass_standards.trigger_check import (
check_no_print_statements,
)
result = check_no_print_statements(content, lines, "/fake/handler.py")
assert result["passed"] is True
# ===========================================================================
# 11. trigger_check -- check_trigger_import_pattern
# ===========================================================================
def test_trigger_import_pattern_correct():
"""Correct trigger import pattern passes."""
content = 'from trigger import trigger\n\ndef do_work():\n trigger.fire("event")\n'
lines = _lines(content)
from aipass.seedgo.apps.handlers.aipass_standards.trigger_check import (
check_trigger_import_pattern,
)
result = check_trigger_import_pattern(content, lines, "/fake/module.py")
assert result is not None
assert result["passed"] is True
def test_trigger_import_pattern_missing():
"""trigger.fire() without import fails."""
content = 'def do_work():\n trigger.fire("event")\n'
lines = _lines(content)
from aipass.seedgo.apps.handlers.aipass_standards.trigger_check import (
check_trigger_import_pattern,
)
result = check_trigger_import_pattern(content, lines, "/fake/module.py")
assert result is not None
assert result["passed"] is False
assert "missing proper import" in result["message"]
def test_trigger_import_pattern_no_trigger():
"""File not using trigger returns None."""
content = "def do_work():\n return True\n"
lines = _lines(content)
from aipass.seedgo.apps.handlers.aipass_standards.trigger_check import (
check_trigger_import_pattern,
)
result = check_trigger_import_pattern(content, lines, "/fake/module.py")
assert result is None
def test_trigger_import_pattern_trigger_branch():
"""Trigger branch file is exempt (self-reference)."""
content = 'def fire(event):\n trigger.fire("event")\n'
lines = _lines(content)
from aipass.seedgo.apps.handlers.aipass_standards.trigger_check import (
check_trigger_import_pattern,
)
result = check_trigger_import_pattern(content, lines, "/src/aipass/trigger/apps/modules/core.py")
assert result is not None
assert result["passed"] is True
# ===========================================================================
# 12. trigger_check -- check_handler_naming
# ===========================================================================
def test_handler_naming_correct():
"""Handler function with handle_ prefix passes."""
content = "def handle_audit_complete(**kwargs):\n pass\n"
lines = _lines(content)
from aipass.seedgo.apps.handlers.aipass_standards.trigger_check import (
check_handler_naming,
)
result = check_handler_naming(content, lines, "/fake/handler.py")
assert result is not None
assert result["passed"] is True
def test_handler_naming_bad():
"""Handler function without handle_ prefix fails."""
content = "def onHandleEvent(**kwargs):\n pass\n"
lines = _lines(content)
from aipass.seedgo.apps.handlers.aipass_standards.trigger_check import (
check_handler_naming,
)
result = check_handler_naming(content, lines, "/fake/handler.py")
assert result is not None
assert result["passed"] is False
def test_handler_naming_no_handlers():
"""File with no handler functions returns None."""
content = "def do_work():\n pass\n"
lines = _lines(content)
from aipass.seedgo.apps.handlers.aipass_standards.trigger_check import (
check_handler_naming,
)
result = check_handler_naming(content, lines, "/fake/handler.py")
assert result is None
# ===========================================================================
# 13. trigger_check -- check_missing_trigger_events
# ===========================================================================
def test_missing_trigger_events_lifecycle():
"""Lifecycle function without trigger.fire() is flagged."""
content = "def create_branch():\n pass\n"
lines = _lines(content)
from aipass.seedgo.apps.handlers.aipass_standards.trigger_check import (
check_missing_trigger_events,
)
result = check_missing_trigger_events(content, lines, "/fake/module.py")
assert result is not None
assert result["passed"] is False
assert "create_" in result["message"]
def test_missing_trigger_events_with_fire():
"""Lifecycle function with trigger.fire() passes (returns None)."""
content = 'def create_branch():\n trigger.fire("branch_created")\n'
lines = _lines(content)
from aipass.seedgo.apps.handlers.aipass_standards.trigger_check import (
check_missing_trigger_events,
)
result = check_missing_trigger_events(content, lines, "/fake/module.py")
assert result is None
def test_missing_trigger_events_no_patterns():
"""File with no event-like patterns returns None."""
content = "def do_work():\n return True\n"
lines = _lines(content)
from aipass.seedgo.apps.handlers.aipass_standards.trigger_check import (
check_missing_trigger_events,
)
result = check_missing_trigger_events(content, lines, "/fake/module.py")
assert result is None
# ===========================================================================
# 14. trigger_check -- find_pattern_lines (via check_missing_trigger_events)
# ===========================================================================
def test_find_pattern_lines_detects_unlink():
"""Inline .unlink() without trigger.fire() is flagged."""
content = "def cleanup():\n path.unlink()\n"
lines = _lines(content)
from aipass.seedgo.apps.handlers.aipass_standards.trigger_check import (
check_missing_trigger_events,
)
result = check_missing_trigger_events(content, lines, "/fake/module.py")
assert result is not None
assert result["passed"] is False
assert ".unlink()" in result["message"]
def test_find_pattern_lines_detects_rename():
"""Inline .rename() without trigger.fire() is flagged."""
content = "def move_file():\n path.rename(new_path)\n"
lines = _lines(content)
from aipass.seedgo.apps.handlers.aipass_standards.trigger_check import (
check_missing_trigger_events,
)
result = check_missing_trigger_events(content, lines, "/fake/module.py")
assert result is not None
assert result["passed"] is False
assert ".rename()" in result["message"]
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,607 @@
"""Tests for seedgo handler functions (audit_display, diagnostics, json extras, readme, hooks_ext)."""
# =================== META ====================
# Name: test_handler_functions.py
# Description: Unit tests for handler-level functions across multiple handler packages
# Version: 1.0.0
# Created: 2026-04-25
# Modified: 2026-04-25
# =============================================
import json
import pytest
from typing import Dict
from unittest.mock import MagicMock, patch
# ---------------------------------------------------------------------------
# Fixtures
# ---------------------------------------------------------------------------
@pytest.fixture(autouse=True)
def _mock_infrastructure(monkeypatch):
"""Mock heavy infrastructure imports for handler functions."""
import sys
mock_logger = MagicMock()
mock_json_handler = MagicMock()
mock_json_handler.log_operation = MagicMock(return_value=True)
# -- prax ---------------------------------------------------------------
prax_mod = MagicMock()
prax_mod.logger = mock_logger
monkeypatch.setitem(sys.modules, "aipass.prax", prax_mod)
# -- seedgo json handler ------------------------------------------------
json_pkg = MagicMock()
json_pkg.json_handler = mock_json_handler
monkeypatch.setitem(sys.modules, "aipass.seedgo.apps.handlers.json", json_pkg)
json_mod = MagicMock()
json_mod.log_operation = mock_json_handler.log_operation
monkeypatch.setitem(sys.modules, "aipass.seedgo.apps.handlers.json.json_handler", json_mod)
# -- bypass handler -----------------------------------------------------
bypass_pkg = MagicMock()
bypass_ignore = MagicMock()
bypass_ignore.get_template_ignore_patterns = MagicMock(return_value=[])
bypass_ignore.get_audit_ignore_patterns = MagicMock(return_value=[])
bypass_pkg.ignore_handler = bypass_ignore
monkeypatch.setitem(sys.modules, "aipass.seedgo.apps.handlers.bypass", bypass_pkg)
monkeypatch.setitem(
sys.modules,
"aipass.seedgo.apps.handlers.bypass.ignore_handler",
bypass_ignore,
)
# -- cli (console for audit_display) ------------------------------------
mock_console = MagicMock()
cli_mod = MagicMock()
cli_mod.console = mock_console
monkeypatch.setitem(sys.modules, "aipass.cli", cli_mod)
# -- cli.apps.modules (warning function for hooks_ext) ------------------
cli_apps = MagicMock()
cli_apps_modules = MagicMock()
cli_apps_modules.warning = MagicMock()
cli_apps.modules = cli_apps_modules
cli_mod.apps = cli_apps
monkeypatch.setitem(sys.modules, "aipass.cli.apps", cli_apps)
monkeypatch.setitem(sys.modules, "aipass.cli.apps.modules", cli_apps_modules)
# -- file handler (for hooks_ext) ---------------------------------------
file_handler_mod = MagicMock()
file_handler_mod.read_lines_safe = MagicMock(return_value=[])
file_handler_mod.read_text_safe = MagicMock(return_value=None)
monkeypatch.setitem(sys.modules, "aipass.seedgo.apps.handlers.file", file_handler_mod)
# -- hooks handler (for hooks_ext) --------------------------------------
hooks_handler_mod = MagicMock()
hooks_handler_mod.run_pytest_file = MagicMock(return_value=(3, 0, 1.5))
monkeypatch.setitem(sys.modules, "aipass.seedgo.apps.handlers.hooks", hooks_handler_mod)
# -- rich.table (for hooks_ext) -----------------------------------------
rich_table_mod = MagicMock()
monkeypatch.setitem(sys.modules, "rich.table", rich_table_mod)
monkeypatch.setitem(sys.modules, "rich", MagicMock())
monkeypatch.setitem(sys.modules, "rich.console", MagicMock())
# Force re-imports so handler modules pick up fresh mocks
for mod_name in [
"aipass.seedgo.apps.handlers.audit.audit_display",
"aipass.seedgo.apps.handlers.diagnostics.diagnostics_check",
"aipass.seedgo.apps.handlers.json.json_handler",
"aipass.seedgo.apps.handlers.readme.readme_ops",
"aipass.seedgo.apps.handlers.readme.readme_generator",
"aipass.seedgo.apps.modules.hooks_ext",
]:
monkeypatch.delitem(sys.modules, mod_name, raising=False)
# ===========================================================================
# 1. audit_display -- print_branch_summary
# ===========================================================================
def test_print_branch_summary_basic():
"""print_branch_summary runs without error on minimal audit result."""
from aipass.seedgo.apps.handlers.audit.audit_display import print_branch_summary
audit_result: Dict = {
"branch": {"name": "seedgo"},
"scores": {"meta": 100, "naming": 90},
"average": 95,
"files_checked": 10,
"results": {},
}
# Should not raise
print_branch_summary(audit_result)
def test_print_branch_summary_with_violations():
"""print_branch_summary handles violation lists."""
from aipass.seedgo.apps.handlers.audit.audit_display import print_branch_summary
audit_result: Dict = {
"branch": {"name": "testbranch"},
"scores": {"meta": 60, "naming": 80},
"average": 70,
"files_checked": 5,
"results": {
"meta": {"checks": [{"name": "META block present", "passed": False, "message": "Missing META block"}]}
},
"meta_violations": [{"path": "file.py", "score": 50, "issues": ["Missing META block"]}],
}
# Should not raise
print_branch_summary(audit_result)
def test_print_branch_summary_with_system_averages():
"""print_branch_summary handles optional system averages."""
from aipass.seedgo.apps.handlers.audit.audit_display import print_branch_summary
audit_result: Dict = {
"branch": {"name": "seedgo"},
"scores": {"meta": 100},
"average": 100,
"files_checked": 1,
"results": {},
}
system_averages: Dict[str, int] = {"meta": 90}
# Should not raise
print_branch_summary(audit_result, system_averages, 90)
# ===========================================================================
# 2. diagnostics_check -- check_directory
# ===========================================================================
def test_check_directory_missing(tmp_path):
"""check_directory on nonexistent directory returns error."""
from aipass.seedgo.apps.handlers.diagnostics.diagnostics_check import (
check_directory,
)
result = check_directory(str(tmp_path / "nonexistent"))
assert result["total_files"] == 0
assert "error" in result
assert "not found" in result["error"].lower()
def test_check_directory_exists(tmp_path):
"""check_directory on existing directory calls pyright."""
# Create a Python file
py_file = tmp_path / "example.py"
py_file.write_text("x = 1\n", encoding="utf-8")
from aipass.seedgo.apps.handlers.diagnostics.diagnostics_check import (
check_directory,
)
with patch("subprocess.run") as mock_run:
mock_run.return_value = MagicMock(
stdout=json.dumps(
{
"generalDiagnostics": [],
"summary": {"filesAnalyzed": 1},
}
),
stderr="",
)
result = check_directory(str(tmp_path))
assert result["total_errors"] == 0
assert result["total_files"] == 1
def test_check_directory_with_errors(tmp_path):
"""check_directory reports errors from pyright output."""
py_file = tmp_path / "bad.py"
py_file.write_text("x: int = 'not_int'\n", encoding="utf-8")
from aipass.seedgo.apps.handlers.diagnostics.diagnostics_check import (
check_directory,
)
with patch("subprocess.run") as mock_run:
mock_run.return_value = MagicMock(
stdout=json.dumps(
{
"generalDiagnostics": [
{
"file": str(py_file),
"severity": "error",
"range": {"start": {"line": 0}},
"message": "Type mismatch",
"rule": "reportAssignment",
}
],
"summary": {"filesAnalyzed": 1},
}
),
stderr="",
)
result = check_directory(str(tmp_path))
assert result["total_errors"] == 1
assert result["files_with_errors"] == 1
# ===========================================================================
# 3. json_handler -- increment_counter
# ===========================================================================
def _get_real_json_handler(tmp_path, monkeypatch):
"""Import the real json_handler module with a tmp_path JSON directory."""
import importlib
import sys
# Remove ALL json_handler mocks/caches so a fresh import is forced
keys_to_remove = [k for k in sys.modules if "json_handler" in k or "handlers.json" in k]
for key in keys_to_remove:
sys.modules.pop(key, None)
# Ensure prax logger mock is in place for the real module
prax = MagicMock()
sys.modules["aipass.prax"] = prax
# Fresh import of the real module
jh_mod = importlib.import_module("aipass.seedgo.apps.handlers.json.json_handler")
monkeypatch.setattr(jh_mod, "_BRANCH_ROOT", tmp_path)
monkeypatch.setattr(jh_mod, "_BRANCH_NAME", "test")
monkeypatch.setattr(jh_mod, "JSON_DIR", tmp_path / "test_json")
return jh_mod
def test_increment_counter(tmp_path, monkeypatch):
"""increment_counter increments a named counter in data JSON."""
jh = _get_real_json_handler(tmp_path, monkeypatch)
result = jh.increment_counter("testmod", "runs", 1)
assert result is True
# Verify counter was set
data = jh.load_json("testmod", "data")
assert data is not None
assert data["runs"] == 1
# Increment again
jh.increment_counter("testmod", "runs", 5)
data = jh.load_json("testmod", "data")
assert data is not None
assert data["runs"] == 6
def test_increment_counter_new_counter(tmp_path, monkeypatch):
"""increment_counter creates a new counter if it does not exist."""
jh = _get_real_json_handler(tmp_path, monkeypatch)
result = jh.increment_counter("testmod", "new_counter", 10)
assert result is True
data = jh.load_json("testmod", "data")
assert data is not None
assert data["new_counter"] == 10
# ===========================================================================
# 4. json_handler -- update_data_metrics
# ===========================================================================
def test_update_data_metrics(tmp_path, monkeypatch):
"""update_data_metrics sets arbitrary metrics in data JSON."""
jh = _get_real_json_handler(tmp_path, monkeypatch)
result = jh.update_data_metrics("testmod", score=95, status="ok")
assert result is True
data = jh.load_json("testmod", "data")
assert data is not None
assert data["score"] == 95
assert data["status"] == "ok"
def test_update_data_metrics_overwrites(tmp_path, monkeypatch):
"""update_data_metrics overwrites existing metrics."""
jh = _get_real_json_handler(tmp_path, monkeypatch)
jh.update_data_metrics("testmod", score=50)
jh.update_data_metrics("testmod", score=99)
data = jh.load_json("testmod", "data")
assert data is not None
assert data["score"] == 99
# ===========================================================================
# 5. readme_ops -- resolve_branch
# ===========================================================================
def test_resolve_branch_found(tmp_path, monkeypatch):
"""resolve_branch finds a branch in the registry."""
registry_data = {
"branches": [
{"name": "seedgo", "path": "/src/aipass/seedgo"},
{"name": "drone", "path": "/src/aipass/drone"},
]
}
registry_path = tmp_path / "AIPASS_REGISTRY.json"
registry_path.write_text(json.dumps(registry_data), encoding="utf-8")
from aipass.seedgo.apps.handlers.readme import readme_ops
monkeypatch.setattr(readme_ops, "_find_registry", lambda: registry_path)
result = readme_ops.resolve_branch("@seedgo")
assert result is not None
assert result["name"] == "seedgo"
def test_resolve_branch_not_found(tmp_path, monkeypatch):
"""resolve_branch returns None for unknown branch."""
registry_data = {"branches": [{"name": "seedgo"}]}
registry_path = tmp_path / "AIPASS_REGISTRY.json"
registry_path.write_text(json.dumps(registry_data), encoding="utf-8")
from aipass.seedgo.apps.handlers.readme import readme_ops
monkeypatch.setattr(readme_ops, "_find_registry", lambda: registry_path)
result = readme_ops.resolve_branch("@nonexistent")
assert result is None
def test_resolve_branch_no_registry(tmp_path, monkeypatch):
"""resolve_branch returns None when registry does not exist."""
from aipass.seedgo.apps.handlers.readme import readme_ops
monkeypatch.setattr(readme_ops, "_find_registry", lambda: tmp_path / "MISSING.json")
result = readme_ops.resolve_branch("@seedgo")
assert result is None
def test_resolve_branch_alias(tmp_path, monkeypatch):
"""resolve_branch resolves aliases."""
registry_data = {
"branches": [
{"name": "seedgo", "aliases": ["@sg", "@standards"]},
]
}
registry_path = tmp_path / "AIPASS_REGISTRY.json"
registry_path.write_text(json.dumps(registry_data), encoding="utf-8")
from aipass.seedgo.apps.handlers.readme import readme_ops
monkeypatch.setattr(readme_ops, "_find_registry", lambda: registry_path)
result = readme_ops.resolve_branch("@sg")
assert result is not None
assert result["name"] == "seedgo"
# ===========================================================================
# 6. readme_ops -- get_all_branches
# ===========================================================================
def test_get_all_branches(tmp_path, monkeypatch):
"""get_all_branches returns all branches from registry."""
registry_data = {
"branches": [
{"name": "seedgo"},
{"name": "drone"},
{"name": "spawn"},
]
}
registry_path = tmp_path / "AIPASS_REGISTRY.json"
registry_path.write_text(json.dumps(registry_data), encoding="utf-8")
from aipass.seedgo.apps.handlers.readme import readme_ops
monkeypatch.setattr(readme_ops, "_find_registry", lambda: registry_path)
branches = readme_ops.get_all_branches()
assert len(branches) == 3
def test_get_all_branches_empty_registry(tmp_path, monkeypatch):
"""get_all_branches returns empty list when registry has no branches."""
registry_path = tmp_path / "AIPASS_REGISTRY.json"
registry_path.write_text(json.dumps({"branches": []}), encoding="utf-8")
from aipass.seedgo.apps.handlers.readme import readme_ops
monkeypatch.setattr(readme_ops, "_find_registry", lambda: registry_path)
branches = readme_ops.get_all_branches()
assert branches == []
def test_get_all_branches_no_registry(tmp_path, monkeypatch):
"""get_all_branches returns empty list when registry is missing."""
from aipass.seedgo.apps.handlers.readme import readme_ops
monkeypatch.setattr(readme_ops, "_find_registry", lambda: tmp_path / "MISSING.json")
branches = readme_ops.get_all_branches()
assert branches == []
# ===========================================================================
# 7. readme_generator -- generate_commands_section
# ===========================================================================
def test_generate_commands_section_no_entry_point(tmp_path):
"""generate_commands_section returns empty when no entry point exists."""
branch_dir = tmp_path / "mybranch"
apps_dir = branch_dir / "apps"
apps_dir.mkdir(parents=True)
from aipass.seedgo.apps.handlers.readme.readme_generator import (
generate_commands_section,
)
result = generate_commands_section(str(branch_dir))
assert result == ""
def test_generate_commands_section_with_help(tmp_path):
"""generate_commands_section parses help output."""
branch_dir = tmp_path / "mybranch"
apps_dir = branch_dir / "apps"
apps_dir.mkdir(parents=True)
entry = apps_dir / "mybranch.py"
entry.write_text("pass", encoding="utf-8")
from aipass.seedgo.apps.handlers.readme.readme_generator import (
generate_commands_section,
)
with patch("subprocess.run") as mock_run:
mock_run.return_value = MagicMock(
stdout="Commands: audit, report, check\n",
stderr="",
)
result = generate_commands_section(str(branch_dir))
assert "audit" in result
assert "report" in result
# ===========================================================================
# 8. readme_generator -- generate_header_section
# ===========================================================================
def test_generate_header_section_with_passport(tmp_path):
"""generate_header_section reads passport.json and produces header."""
branch_dir = tmp_path / "mybranch"
trinity_dir = branch_dir / ".trinity"
trinity_dir.mkdir(parents=True)
passport = {
"branch_info": {
"branch_name": "MYBRANCH",
"path": str(branch_dir),
"profile": "library",
"created": "2026-01-01",
"role": "Testing branch",
}
}
(trinity_dir / "passport.json").write_text(json.dumps(passport), encoding="utf-8")
from aipass.seedgo.apps.handlers.readme.readme_generator import (
generate_header_section,
)
result = generate_header_section(str(branch_dir))
assert "MYBRANCH" in result
assert "library" in result
assert "Testing branch" in result
def test_generate_header_section_no_passport(tmp_path):
"""generate_header_section returns empty when passport is missing."""
branch_dir = tmp_path / "mybranch"
branch_dir.mkdir()
from aipass.seedgo.apps.handlers.readme.readme_generator import (
generate_header_section,
)
result = generate_header_section(str(branch_dir))
assert result == ""
# ===========================================================================
# 9. readme_generator -- update_readme_auto_sections
# ===========================================================================
def test_update_readme_auto_sections_dry_run(tmp_path):
"""update_readme_auto_sections in dry_run mode does not modify the file."""
branch_dir = tmp_path / "mybranch"
branch_dir.mkdir()
readme = branch_dir / "README.md"
original = "# Branch\n<!-- AUTO:LAST_UPDATED -->\n*Last Updated: 2025-01-01*\n<!-- /AUTO:LAST_UPDATED -->\n"
readme.write_text(original, encoding="utf-8")
from aipass.seedgo.apps.handlers.readme.readme_generator import (
update_readme_auto_sections,
)
result = update_readme_auto_sections(str(branch_dir), dry_run=True)
assert result["dry_run"] is True
# File should not be modified in dry run
assert readme.read_text(encoding="utf-8") == original
def test_update_readme_auto_sections_no_readme(tmp_path):
"""update_readme_auto_sections reports error when README is missing."""
branch_dir = tmp_path / "mybranch"
branch_dir.mkdir()
from aipass.seedgo.apps.handlers.readme.readme_generator import (
update_readme_auto_sections,
)
result = update_readme_auto_sections(str(branch_dir))
assert "README.md not found" in result["errors"]
def test_update_readme_auto_sections_missing_markers(tmp_path):
"""update_readme_auto_sections reports missing markers."""
branch_dir = tmp_path / "mybranch"
branch_dir.mkdir()
readme = branch_dir / "README.md"
readme.write_text("# Branch\nNo markers here.\n", encoding="utf-8")
from aipass.seedgo.apps.handlers.readme.readme_generator import (
update_readme_auto_sections,
)
result = update_readme_auto_sections(str(branch_dir))
# Some sections should report missing markers
assert len(result["missing_markers"]) > 0 or len(result["updated"]) == 0
# ===========================================================================
# 10. hooks_ext -- run_hooks_test
# ===========================================================================
def test_run_hooks_test_no_files(tmp_path):
"""run_hooks_test with no test files shows warning."""
from aipass.seedgo.apps.modules.hooks_ext import run_hooks_test
# repo_root with no test_hooks*.py files
run_hooks_test(tmp_path)
# Should call warning() -- verify through mock
import sys
cli_modules = sys.modules["aipass.cli.apps.modules"]
cli_modules.warning.assert_called()
def test_run_hooks_test_with_files(tmp_path):
"""run_hooks_test with test files builds and prints table."""
import sys
# Create the expected directory structure
test_dir = tmp_path / "src" / "aipass" / "seedgo" / "tests"
test_dir.mkdir(parents=True)
(test_dir / "test_hooks_basic.py").write_text("pass", encoding="utf-8")
from aipass.seedgo.apps.modules.hooks_ext import run_hooks_test
run_hooks_test(tmp_path)
# Verify console.print was called (table output)
cli_mod = sys.modules["aipass.cli"]
assert cli_mod.console.print.called