forked from cleveragents/cleveragents-core
139 lines
4.7 KiB
Python
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")
|