Files
cleveragents-core/features/steps/complexity_check_steps.py

139 lines
4.7 KiB
Python

"""Step definitions for complexity check configuration feature."""
from __future__ import annotations
import ast
import re
from pathlib import Path
from typing import Any
import yaml
from behave import then, when
PROJECT_ROOT = Path(__file__).resolve().parent.parent.parent
@when("I read the complexity session source from noxfile.py")
def step_read_complexity_session(context: Any) -> None:
content = context.noxfile_content
pattern = r"(def complexity\(.*?\n(?:(?: .*\n|[ \t]*\n)*))"
match = re.search(pattern, content)
if match is None:
raise ValueError("complexity function not found in noxfile.py")
context.complexity_session_source = match.group(1)
@then("the complexity session should invoke radon cc")
def step_check_radon_cc(context: Any) -> None:
source = context.complexity_session_source
if "radon" not in source or "cc" not in source:
raise AssertionError("complexity session does not invoke 'radon cc'")
@then("the complexity session should target src/cleveragents")
def step_check_target_dir(context: Any) -> None:
source = context.complexity_session_source
if "src/cleveragents" not in source:
raise AssertionError("complexity session does not target src/cleveragents")
@then("the complexity session should export JSON to build directory")
def step_check_json_export(context: Any) -> None:
source = context.complexity_session_source
if "--json" not in source:
raise AssertionError(
"complexity session does not export JSON (missing --json flag)"
)
if "build/" not in source:
raise AssertionError(
"complexity session JSON output is not under build/ directory"
)
@when("I parse the COMPLEXITY_FAIL_GRADE constant from noxfile.py")
def step_parse_fail_grade(context: Any) -> None:
content = context.noxfile_content
tree = ast.parse(content)
grade = None
for node in ast.walk(tree):
if isinstance(node, ast.Assign):
for target in node.targets:
if (
isinstance(target, ast.Name)
and target.id == "COMPLEXITY_FAIL_GRADE"
and isinstance(node.value, ast.Constant)
):
grade = node.value.value
if grade is None:
raise ValueError("COMPLEXITY_FAIL_GRADE constant not found in noxfile.py")
context.complexity_fail_grade = grade
@then('the complexity fail grade should be "{expected}"')
def step_check_fail_grade(context: Any, expected: str) -> None:
actual = context.complexity_fail_grade
if actual != expected:
raise AssertionError(
f"Expected complexity fail grade '{expected}', got '{actual}'"
)
@then("the complexity session should emit a COMPLEXITY OK summary line")
def step_check_ok_summary(context: Any) -> None:
source = context.complexity_session_source
if "COMPLEXITY OK:" not in source:
raise AssertionError(
"complexity session does not emit 'COMPLEXITY OK:' summary"
)
@then("the complexity session should emit a COMPLEXITY FAILED summary line")
def step_check_failed_summary(context: Any) -> None:
source = context.complexity_session_source
if "COMPLEXITY FAILED:" not in source:
raise AssertionError(
"complexity session does not emit 'COMPLEXITY FAILED:' summary"
)
@when("I parse the quality job from the CI workflow")
def step_parse_ci_quality(context: Any) -> None:
content = context.ci_file_content
data = yaml.safe_load(content)
jobs = data.get("jobs", {})
quality_job = jobs.get("quality", {})
if not quality_job:
raise ValueError("No 'quality' job found in CI workflow")
context.ci_quality_job = quality_job
@then("the quality job should run nox -s complexity")
def step_check_ci_quality_nox(context: Any) -> None:
job = context.ci_quality_job
steps = job.get("steps", [])
found = False
for step in steps:
run_cmd = step.get("run", "")
if "nox -s complexity" in run_cmd:
found = True
break
if not found:
raise AssertionError("CI quality job does not contain 'nox -s complexity'")
@then("the quality job should upload complexity artifacts")
def step_check_ci_quality_artifacts(context: Any) -> None:
job = context.ci_quality_job
steps = job.get("steps", [])
found = False
for step in steps:
uses = step.get("uses", "")
if "upload-artifact" in uses:
with_section = step.get("with", {})
path = with_section.get("path", "")
if "complexity" in path:
found = True
break
if not found:
raise AssertionError("CI quality job does not upload complexity artifacts")