{
    "sourceFile": "cleanroom/tests/bdd/steps/scenario_dsl_steps.rs",
    "activeCommit": 0,
    "commits": [
        {
            "activePatchIndex": 0,
            "patches": [
                {
                    "date": 1760261841878,
                    "content": "Index: \n===================================================================\n--- \n+++ \n"
                }
            ],
            "date": 1760261841878,
            "name": "Commit-0",
            "content": "use super::super::world::{CleanroomWorld, ScenarioDefinition, ScenarioStep};\nuse cucumber::{given, then, when};\nuse std::time::Instant;\n\n/// Scenario DSL step definitions for Cleanroom BDD tests\n///\n/// These steps handle scenario definition and execution\n/// for multi-step workflows and concurrent operations.\n\n// ============================================================================\n// GIVEN steps - Setup preconditions\n// ============================================================================\n\n#[given(regex = r\"^a fixture project \"([^\"]+)\"$\")]\nfn fixture_project(world: &mut CleanroomWorld, project: String) {\n    world.set_fixture_project(project, \"target/debug/mock-binary\".to_string());\n}\n\n// ============================================================================\n// WHEN steps - Execute actions\n// ============================================================================\n\n#[when(regex = r\"^I define scenario \"([^\"]+)\"$\")]\nfn define_scenario(world: &mut CleanroomWorld, scenario_name: String) {\n    // Create a basic scenario definition\n    let scenario = ScenarioDefinition {\n        name: scenario_name.clone(),\n        steps: vec![\n            ScenarioStep {\n                name: \"version\".to_string(),\n                args: vec![\"--version\".to_string()],\n                expect: \"success\".to_string(),\n                max_output: None,\n            },\n            ScenarioStep {\n                name: \"build prod\".to_string(),\n                args: vec![\"build\".to_string(), \"--prod\".to_string()],\n                expect: \"success\".to_string(),\n                max_output: None,\n            },\n        ],\n        concurrent: false,\n        continue_on_fail: false,\n    };\n    \n    world.add_scenario(scenario);\n    world.set_current_scenario(scenario_name);\n}\n\n#[when(regex = r\"^I define concurrent scenario \"([^\"]+)\"$\")]\nfn define_concurrent_scenario(world: &mut CleanroomWorld, scenario_name: String) {\n    // Create a concurrent scenario definition\n    let scenario = ScenarioDefinition {\n        name: scenario_name.clone(),\n        steps: vec![\n            ScenarioStep {\n                name: \"help1\".to_string(),\n                args: vec![\"--help\".to_string()],\n                expect: \"success\".to_string(),\n                max_output: Some(64 * 1024), // 64KB\n            },\n            ScenarioStep {\n                name: \"help2\".to_string(),\n                args: vec![\"--help\".to_string()],\n                expect: \"success\".to_string(),\n                max_output: Some(64 * 1024), // 64KB\n            },\n        ],\n        concurrent: true,\n        continue_on_fail: false,\n    };\n    \n    world.add_scenario(scenario);\n    world.set_current_scenario(scenario_name);\n}\n\n#[when(regex = r\"^I execute the scenario on backend \"([^\"]+)\"$\")]\nfn execute_scenario_on_backend(world: &mut CleanroomWorld, backend: String) {\n    let scenario_name = world.current_scenario.as_ref()\n        .expect(\"Current scenario should be set\");\n    \n    let scenario = world.scenarios.get(scenario_name)\n        .expect(\"Scenario should be defined\");\n    \n    let start_time = Instant::now();\n    \n    // Mock scenario execution\n    let mut steps_succeeded = Vec::new();\n    let mut steps_failed = Vec::new();\n    \n    for step in &scenario.steps {\n        // Mock step execution\n        if step.expect == \"success\" {\n            steps_succeeded.push(step.name.clone());\n        } else {\n            steps_failed.push(step.name.clone());\n        }\n    }\n    \n    let duration = start_time.elapsed();\n    \n    // Store scenario result\n    let result = super::super::world::ScenarioResult {\n        scenario_name: scenario_name.clone(),\n        steps_succeeded,\n        steps_failed,\n        total_duration_ms: duration.as_millis() as u64,\n        aggregated_duration_ms: duration.as_millis() as u64,\n    };\n    \n    world.scenario_results.insert(scenario_name.clone(), result);\n    world.set_backend(backend);\n}\n\n// ============================================================================\n// THEN steps - Verify outcomes\n// ============================================================================\n\n#[then(regex = r\"^all steps succeeded$\")]\nfn all_steps_succeeded(world: &mut CleanroomWorld) {\n    let scenario_name = world.current_scenario.as_ref()\n        .expect(\"Current scenario should be set\");\n    \n    let result = world.scenario_results.get(scenario_name)\n        .expect(\"Scenario result should exist\");\n    \n    assert!(\n        result.steps_failed.is_empty(),\n        \"All steps should succeed, but {} failed: {:?}\",\n        result.steps_failed.len(),\n        result.steps_failed\n    );\n}\n\n#[then(regex = r\"^aggregated duration <= (\\d+) ms$\")]\nfn aggregated_duration_less_than(world: &mut CleanroomWorld, max_duration_ms: u64) {\n    let scenario_name = world.current_scenario.as_ref()\n        .expect(\"Current scenario should be set\");\n    \n    let result = world.scenario_results.get(scenario_name)\n        .expect(\"Scenario result should exist\");\n    \n    assert!(\n        result.aggregated_duration_ms <= max_duration_ms,\n        \"Aggregated duration should be <= {} ms, but got {} ms\",\n        max_duration_ms, result.aggregated_duration_ms\n    );\n}\n\n#[then(regex = r\"^step order is deterministic$\")]\nfn step_order_is_deterministic(world: &mut CleanroomWorld) {\n    let scenario_name = world.current_scenario.as_ref()\n        .expect(\"Current scenario should be set\");\n    \n    let scenario = world.scenarios.get(scenario_name)\n        .expect(\"Scenario should be defined\");\n    \n    // Verify that steps are in the expected order\n    let expected_order = vec![\"version\", \"build prod\"];\n    let actual_order: Vec<&str> = scenario.steps.iter().map(|s| s.name.as_str()).collect();\n    \n    assert_eq!(\n        actual_order, expected_order,\n        \"Step order should be deterministic\"\n    );\n}\n\n#[then(regex = r\"^logs are order-stable by \\(start_ts, step_name\\)$\")]\nfn logs_are_order_stable(world: &mut CleanroomWorld) {\n    // Verify that logs are ordered by start timestamp and step name\n    // In a real implementation, this would check the actual log ordering\n    \n    let scenario_name = world.current_scenario.as_ref()\n        .expect(\"Current scenario should be set\");\n    \n    let result = world.scenario_results.get(scenario_name)\n        .expect(\"Scenario result should exist\");\n    \n    // Verify that we have results to check ordering\n    assert!(\n        !result.steps_succeeded.is_empty(),\n        \"Should have succeeded steps to check ordering\"\n    );\n}\n\n#[then(regex = r\"^both steps succeeded$\")]\nfn both_steps_succeeded(world: &mut CleanroomWorld) {\n    let scenario_name = world.current_scenario.as_ref()\n        .expect(\"Current scenario should be set\");\n    \n    let result = world.scenario_results.get(scenario_name)\n        .expect(\"Scenario result should exist\");\n    \n    assert_eq!(\n        result.steps_succeeded.len(), 2,\n        \"Both steps should succeed, but {} succeeded\",\n        result.steps_succeeded.len()\n    );\n}\n\n#[then(regex = r\"^total duration < 2x single-step duration$\")]\nfn total_duration_less_than_double_single_step(world: &mut CleanroomWorld) {\n    let scenario_name = world.current_scenario.as_ref()\n        .expect(\"Current scenario should be set\");\n    \n    let result = world.scenario_results.get(scenario_name)\n        .expect(\"Scenario result should exist\");\n    \n    // Mock single step duration (in real implementation, this would be measured)\n    let single_step_duration_ms = 100;\n    let max_duration_ms = 2 * single_step_duration_ms;\n    \n    assert!(\n        result.total_duration_ms < max_duration_ms,\n        \"Total duration should be < {} ms (2x single-step), but got {} ms\",\n        max_duration_ms, result.total_duration_ms\n    );\n}\n\n#[then(regex = r\"^per-step output <= max_output$\")]\nfn per_step_output_less_than_max(world: &mut CleanroomWorld) {\n    let scenario_name = world.current_scenario.as_ref()\n        .expect(\"Current scenario should be set\");\n    \n    let scenario = world.scenarios.get(scenario_name)\n        .expect(\"Scenario should be defined\");\n    \n    // Verify that each step has max_output set\n    for step in &scenario.steps {\n        assert!(\n            step.max_output.is_some(),\n            \"Step '{}' should have max_output set\",\n            step.name\n        );\n    }\n}\n"
        }
    ]
}