forked from HAL9000/cleveragents-core
314 lines
11 KiB
Python
314 lines
11 KiB
Python
"""Step definitions for workflow parity feature."""
|
|
|
|
import json
|
|
from pathlib import Path
|
|
|
|
from behave import given, then, when
|
|
|
|
from cleveragents.discovery.workflow_parity import WorkflowParityExtractor
|
|
|
|
|
|
@given("the workflow parity extractor is initialized")
|
|
def step_init_workflow_extractor(context):
|
|
"""Initialize the workflow parity extractor."""
|
|
plandex_dir = Path(__file__).parent.parent.parent / "plandex"
|
|
context.workflow_extractor = WorkflowParityExtractor(plandex_dir)
|
|
|
|
|
|
@when("I run the workflow parity extraction")
|
|
def step_run_workflow_extraction(context):
|
|
"""Run the workflow extraction."""
|
|
context.workflow_results = context.workflow_extractor.extract_all()
|
|
|
|
|
|
@when("I extract workflows and generate the parity matrix")
|
|
def step_extract_and_generate_matrix(context):
|
|
"""Extract workflows and generate parity matrix."""
|
|
context.workflow_results = context.workflow_extractor.extract_all()
|
|
context.parity_matrix = context.workflow_results["matrix"]
|
|
|
|
|
|
@when("I extract plan-related workflows")
|
|
def step_extract_plan_workflows(context):
|
|
"""Extract plan lifecycle workflows."""
|
|
context.workflow_extractor._extract_plan_workflows()
|
|
context.plan_workflows = {
|
|
k: v
|
|
for k, v in context.workflow_extractor.workflows.items()
|
|
if v.get("category") == "plan_lifecycle"
|
|
}
|
|
|
|
|
|
@when("I extract context workflows")
|
|
def step_extract_context_workflows(context):
|
|
"""Extract context management workflows."""
|
|
context.workflow_extractor._extract_context_workflows()
|
|
context.context_workflows = {
|
|
k: v
|
|
for k, v in context.workflow_extractor.workflows.items()
|
|
if v.get("category") == "context_management"
|
|
}
|
|
|
|
|
|
@when("I extract execution workflows")
|
|
def step_extract_execution_workflows(context):
|
|
"""Extract execution workflows."""
|
|
context.workflow_extractor._extract_exec_workflows()
|
|
context.exec_workflows = {
|
|
k: v
|
|
for k, v in context.workflow_extractor.workflows.items()
|
|
if v.get("category") == "execution_flows"
|
|
}
|
|
|
|
|
|
@when("I extract all workflows")
|
|
def step_extract_all_workflows(context):
|
|
"""Extract all workflows."""
|
|
context.workflow_results = context.workflow_extractor.extract_all()
|
|
|
|
|
|
@given("I have extracted workflow mappings")
|
|
def step_have_workflow_mappings(context):
|
|
"""Ensure workflow mappings are extracted."""
|
|
if not hasattr(context, "workflow_results"):
|
|
context.workflow_results = context.workflow_extractor.extract_all()
|
|
|
|
|
|
@when("I save the workflow parity results")
|
|
def step_save_workflow_results(context):
|
|
"""Save workflow parity results."""
|
|
output_dir = Path("build/test_output/workflows")
|
|
context.json_file, context.yaml_file = context.workflow_extractor.save_results(
|
|
output_dir
|
|
)
|
|
|
|
|
|
@then("I should get workflow mappings for all categories")
|
|
def step_check_workflow_categories(context):
|
|
"""Check that all categories have workflows."""
|
|
context.workflow_results["categories"]
|
|
workflows = context.workflow_results["workflows"]
|
|
|
|
# Check that we have workflows in multiple categories
|
|
workflow_categories = set(w.get("category") for w in workflows.values())
|
|
assert len(workflow_categories) > 5, (
|
|
f"Expected multiple categories, got {workflow_categories}"
|
|
)
|
|
|
|
|
|
@then("each workflow should have Go components mapped")
|
|
def step_check_go_components(context):
|
|
"""Check that workflows have Go components."""
|
|
workflows = context.workflow_results["workflows"]
|
|
for workflow_id, workflow in workflows.items():
|
|
assert "go_components" in workflow, f"Missing go_components in {workflow_id}"
|
|
assert len(workflow["go_components"]) > 0, f"No Go components in {workflow_id}"
|
|
|
|
|
|
@then("each workflow should have Python modules assigned")
|
|
def step_check_python_modules(context):
|
|
"""Check that workflows have Python modules."""
|
|
workflows = context.workflow_results["workflows"]
|
|
for workflow_id, workflow in workflows.items():
|
|
assert "python_modules" in workflow, f"Missing python_modules in {workflow_id}"
|
|
assert len(workflow["python_modules"]) > 0, (
|
|
f"No Python modules in {workflow_id}"
|
|
)
|
|
|
|
|
|
@then("the statistics should include workflow counts")
|
|
def step_check_workflow_statistics(context):
|
|
"""Check workflow statistics."""
|
|
stats = context.workflow_results["statistics"]
|
|
assert "total_workflows" in stats
|
|
assert stats["total_workflows"] > 0
|
|
assert "workflows_per_category" in stats
|
|
assert "total_go_components" in stats
|
|
assert "total_python_modules" in stats
|
|
|
|
|
|
@then("the matrix should map Go components to Python modules")
|
|
def step_check_go_to_python_mapping(context):
|
|
"""Check Go to Python mapping in matrix."""
|
|
assert "go_to_python" in context.parity_matrix
|
|
assert len(context.parity_matrix["go_to_python"]) > 0
|
|
|
|
|
|
@then("the matrix should identify coverage gaps")
|
|
def step_check_coverage_gaps(context):
|
|
"""Check that coverage gaps are identified."""
|
|
assert "coverage_gaps" in context.parity_matrix
|
|
# Coverage gaps may be empty if all tests are defined
|
|
|
|
|
|
@then("the matrix should provide implementation order")
|
|
def step_check_implementation_order(context):
|
|
"""Check implementation order in matrix."""
|
|
assert "implementation_order" in context.parity_matrix
|
|
assert len(context.parity_matrix["implementation_order"]) > 0
|
|
|
|
|
|
@then("the implementation order should respect dependencies")
|
|
def step_check_dependency_order(context):
|
|
"""Check that implementation order respects dependencies."""
|
|
order = context.parity_matrix["implementation_order"]
|
|
workflows = context.workflow_results["workflows"]
|
|
|
|
# Basic check - auth workflows should come before workflows that depend on them
|
|
auth_index = -1
|
|
for i, wf_id in enumerate(order):
|
|
if workflows.get(wf_id, {}).get("category") == "authentication":
|
|
auth_index = i
|
|
break
|
|
|
|
# Check that workflows depending on auth come after
|
|
for i, wf_id in enumerate(order):
|
|
wf = workflows.get(wf_id, {})
|
|
if "authentication" in wf.get("dependencies", []):
|
|
assert i > auth_index or auth_index == -1, (
|
|
f"{wf_id} should come after auth workflows"
|
|
)
|
|
|
|
|
|
@then("a JSON file should be created with workflow data")
|
|
def step_check_json_file(context):
|
|
"""Check JSON file creation."""
|
|
assert context.json_file.exists()
|
|
with open(context.json_file) as f:
|
|
data = json.load(f)
|
|
assert "workflows" in data
|
|
assert "matrix" in data
|
|
|
|
|
|
@then("a YAML file should be created with workflow data")
|
|
def step_check_yaml_file(context):
|
|
"""Check YAML file creation."""
|
|
assert context.yaml_file.exists()
|
|
|
|
|
|
@then("a Markdown documentation should be generated")
|
|
def step_check_markdown_doc(context):
|
|
"""Check Markdown documentation."""
|
|
md_file = context.json_file.parent / "workflow_parity.md"
|
|
assert md_file.exists()
|
|
content = md_file.read_text()
|
|
assert "# Workflow Parity Matrix" in content
|
|
|
|
|
|
@then("the documentation should include all workflows by category")
|
|
def step_check_doc_categories(context):
|
|
"""Check documentation includes categories."""
|
|
md_file = context.json_file.parent / "workflow_parity.md"
|
|
content = md_file.read_text()
|
|
for category in context.workflow_results["categories"]:
|
|
category_title = category.replace("_", " ").title()
|
|
assert category_title in content
|
|
|
|
|
|
@then("I should find {workflow_id} workflow")
|
|
def step_find_workflow(context, workflow_id):
|
|
"""Check that a specific workflow exists."""
|
|
# Try to find the workflow in the appropriate context attribute
|
|
if hasattr(context, "plan_workflows") and workflow_id in context.plan_workflows:
|
|
return
|
|
if (
|
|
hasattr(context, "context_workflows")
|
|
and workflow_id in context.context_workflows
|
|
):
|
|
return
|
|
if hasattr(context, "exec_workflows") and workflow_id in context.exec_workflows:
|
|
return
|
|
|
|
# If not found in any specific category, check all workflows
|
|
if hasattr(context, "workflow_extractor"):
|
|
workflows = context.workflow_extractor.workflows
|
|
assert workflow_id in workflows, f"Workflow {workflow_id} not found"
|
|
else:
|
|
raise AssertionError(f"Workflow {workflow_id} not found in any category")
|
|
|
|
|
|
@then("each workflow should have stages defined")
|
|
def step_check_workflow_stages(context):
|
|
"""Check that workflows have stages."""
|
|
workflow_collections = []
|
|
|
|
# Add only the workflow collections that exist
|
|
if hasattr(context, "plan_workflows"):
|
|
workflow_collections.append(context.plan_workflows)
|
|
if hasattr(context, "context_workflows"):
|
|
workflow_collections.append(context.context_workflows)
|
|
if hasattr(context, "exec_workflows"):
|
|
workflow_collections.append(context.exec_workflows)
|
|
|
|
for workflows in workflow_collections:
|
|
if workflows:
|
|
for wf_id, workflow in workflows.items():
|
|
assert "stages" in workflow, f"No stages in {wf_id}"
|
|
assert len(workflow["stages"]) > 0, f"Empty stages in {wf_id}"
|
|
|
|
|
|
@then("each workflow should have test coverage specified")
|
|
def step_check_test_coverage(context):
|
|
"""Check test coverage specification."""
|
|
for workflows in [context.plan_workflows]:
|
|
for wf_id, workflow in workflows.items():
|
|
assert "test_coverage" in workflow, f"No test_coverage in {wf_id}"
|
|
|
|
|
|
@then("the workflows should include heuristics information")
|
|
def step_check_heuristics_info(context):
|
|
"""Check for heuristics information."""
|
|
auto_context = context.context_workflows.get("context_auto")
|
|
assert auto_context is not None
|
|
assert "heuristics" in auto_context.get("notes", "").lower() or any(
|
|
"heuristics" in stage["name"].lower()
|
|
for stage in auto_context.get("stages", [])
|
|
)
|
|
|
|
|
|
@then("the workflows should include retry logic details")
|
|
def step_check_retry_logic(context):
|
|
"""Check for retry logic details."""
|
|
auto_debug = context.exec_workflows.get("auto_debug")
|
|
assert auto_debug is not None
|
|
assert "retry" in auto_debug.get("notes", "").lower() or "retry" in str(
|
|
auto_debug.get("dependencies", [])
|
|
)
|
|
|
|
|
|
@then("the statistics should include total workflows")
|
|
def step_check_total_workflows(context):
|
|
"""Check total workflows statistic."""
|
|
stats = context.workflow_results["statistics"]
|
|
assert stats["total_workflows"] > 0
|
|
|
|
|
|
@then("the statistics should include workflows per category")
|
|
def step_check_workflows_per_category(context):
|
|
"""Check workflows per category statistic."""
|
|
stats = context.workflow_results["statistics"]
|
|
assert len(stats["workflows_per_category"]) > 0
|
|
|
|
|
|
@then("the statistics should include total Go components")
|
|
def step_check_total_go_components(context):
|
|
"""Check total Go components statistic."""
|
|
stats = context.workflow_results["statistics"]
|
|
assert stats["total_go_components"] > 0
|
|
|
|
|
|
@then("the statistics should include total Python modules")
|
|
def step_check_total_python_modules(context):
|
|
"""Check total Python modules statistic."""
|
|
stats = context.workflow_results["statistics"]
|
|
assert stats["total_python_modules"] > 0
|
|
|
|
|
|
@then("the statistics should include test coverage metrics")
|
|
def step_check_test_coverage_metrics(context):
|
|
"""Check test coverage metrics."""
|
|
stats = context.workflow_results["statistics"]
|
|
assert "test_coverage" in stats
|
|
assert "with_behave" in stats["test_coverage"]
|
|
assert "with_robot" in stats["test_coverage"]
|