{
    "sourceFile": "cleanroom/tests/bdd/steps/scenario_steps.rs",
    "activeCommit": 0,
    "commits": [
        {
            "activePatchIndex": 0,
            "patches": [
                {
                    "date": 1760261427411,
                    "content": "Index: \n===================================================================\n--- \n+++ \n"
                }
            ],
            "date": 1760261427411,
            "name": "Commit-0",
            "content": "use super::super::world::CleanroomWorld;\nuse assert_cmd::Command;\nuse cucumber::{given, then, when};\nuse std::fs;\nuse std::path::Path;\n\n/// Scenario step definitions for Cleanroom BDD tests\n///\n/// These steps handle test scenario execution, command running,\n/// and result validation for cleanroom operations.\n\n// ============================================================================\n// GIVEN steps - Setup preconditions\n// ============================================================================\n\n#[given(regex = r\"^I have a test scenario \"([^\"]+)\"$\")]\nfn test_scenario(world: &mut CleanroomWorld, scenario_name: String) {\n    // Create a basic test scenario file\n    let scenario_content = format!(\n        r#\"name: {}\ndescription: Test scenario for cleanroom\nsteps:\n  - name: \"test step\"\n    command: \"echo 'Hello World'\"\n    expected_exit_code: 0\n\"#,\n        scenario_name\n    );\n    \n    let scenario_file = world.project_dir.join(format!(\"{}.yaml\", scenario_name));\n    fs::write(&scenario_file, scenario_content)\n        .unwrap_or_else(|e| panic!(\"Failed to write scenario file: {}\", e));\n    \n    world.capture_file(&format!(\"{}.yaml\", scenario_name), scenario_content);\n}\n\n#[given(regex = r\"^I have a test scenario with steps:$\")]\nfn test_scenario_with_steps(world: &mut CleanroomWorld, steps: String) {\n    // Create a test scenario with custom steps\n    let scenario_content = format!(\n        r#\"name: \"custom_scenario\"\ndescription: Custom test scenario\nsteps:\n{}\n\"#,\n        steps\n    );\n    \n    let scenario_file = world.project_dir.join(\"custom_scenario.yaml\");\n    fs::write(&scenario_file, scenario_content)\n        .unwrap_or_else(|e| panic!(\"Failed to write scenario file: {}\", e));\n    \n    world.capture_file(\"custom_scenario.yaml\", scenario_content);\n}\n\n#[given(regex = r\"^I have a failing test scenario$\")]\nfn failing_test_scenario(world: &mut CleanroomWorld) {\n    // Create a scenario that will fail\n    let scenario_content = r#\"name: \"failing_scenario\"\ndescription: Test scenario that will fail\nsteps:\n  - name: \"failing step\"\n    command: \"false\"\n    expected_exit_code: 0\n\"#;\n    \n    let scenario_file = world.project_dir.join(\"failing_scenario.yaml\");\n    fs::write(&scenario_file, scenario_content)\n        .unwrap_or_else(|e| panic!(\"Failed to write scenario file: {}\", e));\n    \n    world.capture_file(\"failing_scenario.yaml\", scenario_content.to_string());\n}\n\n#[given(regex = r\"^I have a long-running test scenario$\")]\nfn long_running_test_scenario(world: &mut CleanroomWorld) {\n    // Create a scenario that takes time to complete\n    let scenario_content = r#\"name: \"long_running_scenario\"\ndescription: Test scenario that takes time to complete\nsteps:\n  - name: \"sleep step\"\n    command: \"sleep 5\"\n    expected_exit_code: 0\n    timeout: \"10s\"\n\"#;\n    \n    let scenario_file = world.project_dir.join(\"long_running_scenario.yaml\");\n    fs::write(&scenario_file, scenario_content)\n        .unwrap_or_else(|e| panic!(\"Failed to write scenario file: {}\", e));\n    \n    world.capture_file(\"long_running_scenario.yaml\", scenario_content.to_string());\n}\n\n#[given(regex = r\"^I have a test scenario with network access$\")]\nfn test_scenario_with_network(world: &mut CleanroomWorld) {\n    // Create a scenario that requires network access\n    let scenario_content = r#\"name: \"network_scenario\"\ndescription: Test scenario requiring network access\nsteps:\n  - name: \"network test\"\n    command: \"curl -s http://httpbin.org/get\"\n    expected_exit_code: 0\n    network: \"open\"\n\"#;\n    \n    let scenario_file = world.project_dir.join(\"network_scenario.yaml\");\n    fs::write(&scenario_file, scenario_content)\n        .unwrap_or_else(|e| panic!(\"Failed to write scenario file: {}\", e));\n    \n    world.capture_file(\"network_scenario.yaml\", scenario_content.to_string());\n}\n\n#[given(regex = r\"^I have a test scenario with file operations$\")]\nfn test_scenario_with_file_ops(world: &mut CleanroomWorld) {\n    // Create a scenario that performs file operations\n    let scenario_content = r#\"name: \"file_ops_scenario\"\ndescription: Test scenario with file operations\nsteps:\n  - name: \"create file\"\n    command: \"echo 'test content' > test.txt\"\n    expected_exit_code: 0\n  - name: \"read file\"\n    command: \"cat test.txt\"\n    expected_exit_code: 0\n\"#;\n    \n    let scenario_file = world.project_dir.join(\"file_ops_scenario.yaml\");\n    fs::write(&scenario_file, scenario_content)\n        .unwrap_or_else(|e| panic!(\"Failed to write scenario file: {}\", e));\n    \n    world.capture_file(\"file_ops_scenario.yaml\", scenario_content.to_string());\n}\n\n// ============================================================================\n// WHEN steps - Execute actions\n// ============================================================================\n\n#[when(regex = r\"^I run the scenario \"([^\"]+)\"$\")]\nfn run_scenario(world: &mut CleanroomWorld, scenario_name: String) {\n    let scenario_file = world.project_dir.join(format!(\"{}.yaml\", scenario_name));\n    \n    if !scenario_file.exists() {\n        panic!(\"Scenario file '{}' does not exist\", scenario_file.display());\n    }\n    \n    let output = Command::cargo_bin(\"cleanroom\")\n        .expect(\"cleanroom binary not found\")\n        .arg(\"run\")\n        .arg(&scenario_file)\n        .current_dir(&world.project_dir)\n        .output()\n        .unwrap_or_else(|e| panic!(\"Failed to run scenario: {}\", e));\n    \n    world.last_output = Some(output.clone());\n    world.last_exit_code = output.status.code();\n}\n\n#[when(regex = r\"^I run the scenario with policy \"([^\"]+)\"$\")]\nfn run_scenario_with_policy(world: &mut CleanroomWorld, policy_name: String) {\n    let scenario_file = world.project_dir.join(\"custom_scenario.yaml\");\n    let policy_file = world.project_dir.join(&policy_name);\n    \n    if !scenario_file.exists() {\n        panic!(\"Scenario file does not exist\");\n    }\n    \n    if !policy_file.exists() {\n        panic!(\"Policy file '{}' does not exist\", policy_name);\n    }\n    \n    let output = Command::cargo_bin(\"cleanroom\")\n        .expect(\"cleanroom binary not found\")\n        .arg(\"run\")\n        .arg(&scenario_file)\n        .arg(\"--policy\")\n        .arg(&policy_file)\n        .current_dir(&world.project_dir)\n        .output()\n        .unwrap_or_else(|e| panic!(\"Failed to run scenario with policy: {}\", e));\n    \n    world.last_output = Some(output.clone());\n    world.last_exit_code = output.status.code();\n}\n\n#[when(regex = r\"^I run the scenario with backend \"([^\"]+)\"$\")]\nfn run_scenario_with_backend(world: &mut CleanroomWorld, backend: String) {\n    let scenario_file = world.project_dir.join(\"custom_scenario.yaml\");\n    \n    if !scenario_file.exists() {\n        panic!(\"Scenario file does not exist\");\n    }\n    \n    let output = Command::cargo_bin(\"cleanroom\")\n        .expect(\"cleanroom binary not found\")\n        .arg(\"run\")\n        .arg(&scenario_file)\n        .arg(\"--backend\")\n        .arg(&backend)\n        .current_dir(&world.project_dir)\n        .output()\n        .unwrap_or_else(|e| panic!(\"Failed to run scenario with backend: {}\", e));\n    \n    world.last_output = Some(output.clone());\n    world.last_exit_code = output.status.code();\n}\n\n#[when(regex = r\"^I run the scenario with timeout \"([^\"]+)\"$\")]\nfn run_scenario_with_timeout(world: &mut CleanroomWorld, timeout: String) {\n    let scenario_file = world.project_dir.join(\"custom_scenario.yaml\");\n    \n    if !scenario_file.exists() {\n        panic!(\"Scenario file does not exist\");\n    }\n    \n    let output = Command::cargo_bin(\"cleanroom\")\n        .expect(\"cleanroom binary not found\")\n        .arg(\"run\")\n        .arg(&scenario_file)\n        .arg(\"--timeout\")\n        .arg(&timeout)\n        .current_dir(&world.project_dir)\n        .output()\n        .unwrap_or_else(|e| panic!(\"Failed to run scenario with timeout: {}\", e));\n    \n    world.last_output = Some(output.clone());\n    world.last_exit_code = output.status.code();\n}\n\n#[when(regex = r\"^I run the scenario in parallel$\")]\nfn run_scenario_in_parallel(world: &mut CleanroomWorld) {\n    let scenario_file = world.project_dir.join(\"custom_scenario.yaml\");\n    \n    if !scenario_file.exists() {\n        panic!(\"Scenario file does not exist\");\n    }\n    \n    let output = Command::cargo_bin(\"cleanroom\")\n        .expect(\"cleanroom binary not found\")\n        .arg(\"run\")\n        .arg(&scenario_file)\n        .arg(\"--parallel\")\n        .current_dir(&world.project_dir)\n        .output()\n        .unwrap_or_else(|e| panic!(\"Failed to run scenario in parallel: {}\", e));\n    \n    world.last_output = Some(output.clone());\n    world.last_exit_code = output.status.code();\n}\n\n// ============================================================================\n// THEN steps - Verify outcomes\n// ============================================================================\n\n#[then(regex = r\"^the scenario should complete successfully$\")]\nfn scenario_should_complete_successfully(world: &mut CleanroomWorld) {\n    if !world.last_command_succeeded() {\n        eprintln!(\"=== SCENARIO FAILED ===\");\n        eprintln!(\"Exit code: {}\", world.last_exit_code.unwrap_or(-1));\n        eprintln!(\"Stdout:\\n{}\", world.last_stdout());\n        eprintln!(\"Stderr:\\n{}\", world.last_stderr());\n        panic!(\"Scenario should have completed successfully\");\n    }\n}\n\n#[then(regex = r\"^the scenario should fail$\")]\nfn scenario_should_fail(world: &mut CleanroomWorld) {\n    if world.last_command_succeeded() {\n        eprintln!(\"=== SCENARIO UNEXPECTEDLY SUCCEEDED ===\");\n        eprintln!(\"Exit code: {}\", world.last_exit_code.unwrap_or(0));\n        eprintln!(\"Stdout:\\n{}\", world.last_stdout());\n        eprintln!(\"Stderr:\\n{}\", world.last_stderr());\n        panic!(\"Scenario should have failed but succeeded\");\n    }\n}\n\n#[then(regex = r\"^the scenario should timeout$\")]\nfn scenario_should_timeout(world: &mut CleanroomWorld) {\n    // Check for timeout-related output\n    let stdout = world.last_stdout();\n    let stderr = world.last_stderr();\n    \n    if !stdout.contains(\"timeout\") && !stderr.contains(\"timeout\") {\n        eprintln!(\"=== SCENARIO DID NOT TIMEOUT ===\");\n        eprintln!(\"Exit code: {}\", world.last_exit_code.unwrap_or(-1));\n        eprintln!(\"Stdout:\\n{}\", stdout);\n        eprintln!(\"Stderr:\\n{}\", stderr);\n        panic!(\"Scenario should have timed out\");\n    }\n}\n\n#[then(regex = r\"^the scenario should produce output$\")]\nfn scenario_should_produce_output(world: &mut CleanroomWorld) {\n    let stdout = world.last_stdout();\n    \n    if stdout.trim().is_empty() {\n        eprintln!(\"=== SCENARIO PRODUCED NO OUTPUT ===\");\n        eprintln!(\"Exit code: {}\", world.last_exit_code.unwrap_or(-1));\n        eprintln!(\"Stderr:\\n{}\", world.last_stderr());\n        panic!(\"Scenario should have produced output\");\n    }\n}\n\n#[then(regex = r\"^the scenario should create files$\")]\nfn scenario_should_create_files(world: &mut CleanroomWorld) {\n    // Check if any files were created\n    let mut files_created = false;\n    \n    for entry in fs::read_dir(&world.project_dir).unwrap() {\n        let entry = entry.unwrap();\n        if entry.file_type().unwrap().is_file() {\n            files_created = true;\n            break;\n        }\n    }\n    \n    if !files_created {\n        panic!(\"Scenario should have created files\");\n    }\n}\n\n#[then(regex = r\"^the scenario should respect network constraints$\")]\nfn scenario_should_respect_network_constraints(world: &mut CleanroomWorld) {\n    // Verify that network constraints were respected\n    if world.network_constraints.contains(&\"blocked\".to_string()) {\n        // If network is blocked, the scenario should not have made network requests\n        let stdout = world.last_stdout();\n        let stderr = world.last_stderr();\n        \n        if stdout.contains(\"http\") || stderr.contains(\"http\") {\n            panic!(\"Scenario should not have made network requests when network is blocked\");\n        }\n    }\n}\n\n#[then(regex = r\"^the scenario should respect filesystem constraints$\")]\nfn scenario_should_respect_filesystem_constraints(world: &mut CleanroomWorld) {\n    // Verify that filesystem constraints were respected\n    if world.filesystem_constraints.contains(&\"readonly\".to_string()) {\n        // If filesystem is readonly, the scenario should not have created files\n        let stdout = world.last_stdout();\n        let stderr = world.last_stderr();\n        \n        if stdout.contains(\"created\") || stderr.contains(\"created\") {\n            panic!(\"Scenario should not have created files when filesystem is readonly\");\n        }\n    }\n}\n\n#[then(regex = r\"^the scenario should complete within the timeout$\")]\nfn scenario_should_complete_within_timeout(world: &mut CleanroomWorld) {\n    // This would typically involve checking execution time\n    // For now, just verify that the scenario completed successfully\n    if !world.last_command_succeeded() {\n        panic!(\"Scenario should have completed within timeout\");\n    }\n}\n\n#[then(regex = r\"^the scenario should produce consistent results$\")]\nfn scenario_should_produce_consistent_results(world: &mut CleanroomWorld) {\n    // Run the scenario multiple times and compare results\n    let first_output = world.last_stdout();\n    \n    // Store the first output hash\n    use std::collections::hash_map::DefaultHasher;\n    use std::hash::{Hash, Hasher};\n    \n    let mut hasher = DefaultHasher::new();\n    first_output.hash(&mut hasher);\n    let first_hash = hasher.finish();\n    \n    world.capture_hash(first_hash.to_string());\n    \n    // This step would typically run the scenario again and compare\n    // For now, just verify that we have output to compare\n    assert!(!first_output.is_empty(), \"Scenario should produce output for consistency checking\");\n}\n"
        }
    ]
}