Feat: Added an --all flag to the context delete command

This commit is contained in:
2025-11-18 20:23:29 -05:00
parent 300fbd1212
commit 5abb0dc02e
5 changed files with 736 additions and 11 deletions
+71 -9
View File
@@ -981,23 +981,85 @@ def clear_context(name: str, context_dir: Optional[Path]) -> None:
@context.command("delete")
@click.argument("name")
@click.argument("name", required=False)
@click.option(
"--context-dir",
type=click.Path(file_okay=False, dir_okay=True, path_type=Path),
help="Directory where contexts are stored.",
)
@click.confirmation_option(prompt="Are you sure you want to delete this context?")
def delete_context(name: str, context_dir: Optional[Path]) -> None:
"""Delete a context and all its data."""
@click.option(
"--all",
is_flag=True,
help="Delete all contexts.",
)
@click.option(
"--yes",
"-y",
is_flag=True,
help="Skip confirmation prompt.",
)
def delete_context(name: Optional[str], context_dir: Optional[Path], all: bool, yes: bool) -> None:
"""Delete a context and all its data, or delete all contexts with --all."""
try:
ctx_manager = ContextManager(name, context_dir)
if not ctx_manager.exists():
click.echo(f"Context '{name}' does not exist.", err=True)
# Validate arguments
if all and name:
click.echo("Error: Cannot specify NAME when using --all flag.", err=True)
sys.exit(1)
ctx_manager.delete()
click.echo(f"Context '{name}' has been deleted.")
if not all and not name:
click.echo("Error: Must specify NAME or use --all flag.", err=True)
sys.exit(1)
if all:
# Delete all contexts
contexts = ContextManager.list_contexts(context_dir)
if not contexts:
click.echo("No contexts found.")
return
# Show what will be deleted
click.echo(f"Found {len(contexts)} context(s) to delete:")
for ctx in contexts:
click.echo(f" - {ctx}")
# Confirmation prompt (unless --yes is provided)
if not yes:
if not click.confirm("Are you sure you want to delete ALL contexts?"):
click.echo("Operation cancelled.")
return
# Delete all contexts
deleted_count = 0
failed_count = 0
for ctx_name in contexts:
try:
ctx_manager = ContextManager(ctx_name, context_dir)
ctx_manager.delete()
deleted_count += 1
except Exception as e: # pylint: disable=broad-exception-caught
click.echo(f"Failed to delete context '{ctx_name}': {e}", err=True)
failed_count += 1
click.echo(f"Deleted {deleted_count} context(s).")
if failed_count > 0:
click.echo(f"Failed to delete {failed_count} context(s).", err=True)
else:
# Delete single context
assert name is not None # mypy type narrowing: guaranteed by validation above
ctx_manager = ContextManager(name, context_dir)
if not ctx_manager.exists():
click.echo(f"Context '{name}' does not exist.", err=True)
sys.exit(1)
# Confirmation prompt (unless --yes is provided)
if not yes:
if not click.confirm(f"Are you sure you want to delete context '{name}'?"):
click.echo("Operation cancelled.")
return
ctx_manager.delete()
click.echo(f"Context '{name}' has been deleted.")
except Exception as e: # pylint: disable=broad-exception-caught
click.echo(f"Error: {e}", err=True)
sys.exit(1)
+14 -2
View File
@@ -227,8 +227,20 @@ class ContextManager:
contexts = []
for path in base_dir.iterdir():
if path.is_dir() and (path / "messages.json").exists():
contexts.append(path.name)
try:
if path.is_dir():
# Try to check if messages.json exists, but if we can't access it
# (due to permissions), assume it's a context directory anyway
try:
if (path / "messages.json").exists():
contexts.append(path.name)
except (PermissionError, OSError):
# Can't access the directory contents, but it might be a context
# Include it anyway and let deletion handle the error
contexts.append(path.name)
except (PermissionError, OSError):
# Can't even check if it's a directory, skip it
continue
return sorted(contexts)
@@ -0,0 +1,86 @@
Feature: Context Delete with --all and --yes Flags
As a user of CleverAgents
I want to delete contexts individually or in bulk with confirmation control
So that I can efficiently manage my stored conversation contexts
Background:
Given I have a temporary test directory for contexts
Scenario: Delete single context with --yes bypasses confirmation
Given I have a context "test-context-1" in the test directory
When I run CLI command "context delete test-context-1 --yes" with test context dir
Then the command should succeed
And the context "test-context-1" should not exist
Scenario: Delete single context without --yes prompts for confirmation
Given I have a context "test-context-2" in the test directory
When I run CLI command "context delete test-context-2" with test context dir and answer "y"
Then the command should succeed
And the context "test-context-2" should not exist
Scenario: Delete single context - cancel confirmation
Given I have a context "test-context-3" in the test directory
When I run CLI command "context delete test-context-3" with test context dir and answer "n"
Then the command should be cancelled
And the context "test-context-3" should still exist
Scenario: Delete all contexts with --all --yes bypasses confirmation
Given I have contexts "ctx-a", "ctx-b", "ctx-c" in the test directory
When I run CLI command "context delete --all --yes" with test context dir
Then the command should succeed
And all contexts should be deleted
And the output should show "Deleted 3 context(s)"
Scenario: Delete all contexts with --all prompts for confirmation
Given I have contexts "ctx-d", "ctx-e" in the test directory
When I run CLI command "context delete --all" with test context dir and answer "y"
Then the command should succeed
And all contexts should be deleted
And the output should list all contexts before deletion
Scenario: Delete all contexts - cancel confirmation
Given I have contexts "ctx-f", "ctx-g" in the test directory
When I run CLI command "context delete --all" with test context dir and answer "n"
Then the command should be cancelled
And the contexts "ctx-f", "ctx-g" should still exist
Scenario: Error when both NAME and --all provided
When I run CLI command "context delete test-context --all" with test context dir
Then the command should fail with error "Cannot specify NAME when using --all flag"
Scenario: Error when neither NAME nor --all provided
When I run CLI command "context delete" with test context dir
Then the command should fail with error "Must specify NAME or use --all flag"
Scenario: Delete all when no contexts exist
Given the test context directory is empty
When I run CLI command "context delete --all --yes" with test context dir
Then the command should succeed
And the output should show "No contexts found"
Scenario: Delete single non-existent context
When I run CLI command "context delete non-existent --yes" with test context dir
Then the command should fail
And the output should show "does not exist"
Scenario: Delete all contexts with partial failures
Given I have contexts "ctx-h", "ctx-i" in the test directory
And context "ctx-i" directory is made read-only
When I run CLI command "context delete --all --yes" with test context dir
Then the command should succeed
And the output should show deleted count
And the output should show failed count
Scenario: Delete all shows context list before confirmation
Given I have contexts "alpha", "beta", "gamma" in the test directory
When I run CLI command "context delete --all" with test context dir and capture output
Then the output should contain "Found 3 context(s) to delete"
And the output should contain "alpha"
And the output should contain "beta"
And the output should contain "gamma"
Scenario: Using -y as shorthand for --yes
Given I have a context "test-short-yes" in the test directory
When I run CLI command "context delete test-short-yes -y" with test context dir
Then the command should succeed
And the context "test-short-yes" should not exist
@@ -0,0 +1,247 @@
"""Step definitions for Context Delete with --all and --yes flags."""
import json
import os
import subprocess
import tempfile
from pathlib import Path
from behave import given, then, when
from behave.runner import Context
@given('I have a context "{name}" in the test directory')
def step_have_context_in_test_dir(context: Context, name: str) -> None:
"""Create a single context in the test directory."""
if not hasattr(context, "context_dir"):
context.temp_dir = tempfile.mkdtemp(prefix="cleveragents_test_")
context.context_dir = Path(context.temp_dir) / "contexts"
context.context_dir.mkdir(parents=True, exist_ok=True)
# Create a simple context structure
ctx_dir = context.context_dir / name
ctx_dir.mkdir(parents=True, exist_ok=True)
# Create the standard context files
(ctx_dir / "messages.json").write_text("[]")
(ctx_dir / "metadata.json").write_text("{}")
(ctx_dir / "state.json").write_text("{}")
(ctx_dir / "global_context.json").write_text("{}")
@given('I have contexts "{names}" in the test directory')
def step_have_multiple_contexts_in_test_dir(context: Context, names: str) -> None:
"""Create multiple contexts in the test directory."""
if not hasattr(context, "context_dir"):
context.temp_dir = tempfile.mkdtemp(prefix="cleveragents_test_")
context.context_dir = Path(context.temp_dir) / "contexts"
context.context_dir.mkdir(parents=True, exist_ok=True)
# Parse the comma-separated names
context_names = [name.strip().strip('"') for name in names.split(",")]
# Create each context
for name in context_names:
ctx_dir = context.context_dir / name
ctx_dir.mkdir(parents=True, exist_ok=True)
# Create the standard context files
(ctx_dir / "messages.json").write_text("[]")
(ctx_dir / "metadata.json").write_text("{}")
(ctx_dir / "state.json").write_text("{}")
(ctx_dir / "global_context.json").write_text("{}")
@given("the test context directory is empty")
def step_empty_test_context_dir(context: Context) -> None:
"""Ensure the test context directory is empty."""
if not hasattr(context, "context_dir"):
context.temp_dir = tempfile.mkdtemp(prefix="cleveragents_test_")
context.context_dir = Path(context.temp_dir) / "contexts"
context.context_dir.mkdir(parents=True, exist_ok=True)
# Directory already empty since we just created it
@given('context "{name}" directory is made read-only')
def step_make_context_readonly(context: Context, name: str) -> None:
"""Make a context directory read-only to simulate failure."""
ctx_dir = context.context_dir / name
if ctx_dir.exists():
# Make directory read-only
os.chmod(ctx_dir, 0o444)
# Track this for cleanup
if not hasattr(context, "readonly_dirs"):
context.readonly_dirs = []
context.readonly_dirs.append(ctx_dir)
@when('I run CLI command "{command}" with test context dir')
def step_run_cli_with_test_context_dir(context: Context, command: str) -> None:
"""Run a CLI command with the test context directory."""
# Parse command and add --context-dir
cmd_parts = ["python", "-m", "cleveragents"] + command.split()
cmd_parts.extend(["--context-dir", str(context.context_dir)])
# Run the command
result = subprocess.run(cmd_parts, capture_output=True, text=True, cwd="/app")
context.cli_result = result
context.cli_stdout = result.stdout
context.cli_stderr = result.stderr
context.cli_returncode = result.returncode
@when('I run CLI command "{command}" with test context dir and answer "{answer}"')
def step_run_cli_with_answer(context: Context, command: str, answer: str) -> None:
"""Run a CLI command with the test context directory and provide input."""
# Parse command and add --context-dir
cmd_parts = ["python", "-m", "cleveragents"] + command.split()
cmd_parts.extend(["--context-dir", str(context.context_dir)])
# Run the command with input
result = subprocess.run(cmd_parts, input=answer + "\n", capture_output=True, text=True, cwd="/app")
context.cli_result = result
context.cli_stdout = result.stdout
context.cli_stderr = result.stderr
context.cli_returncode = result.returncode
@when('I run CLI command "{command}" with test context dir and capture output')
def step_run_cli_and_capture_output(context: Context, command: str) -> None:
"""Run a CLI command with the test context directory and capture all output."""
# Parse command and add --context-dir
cmd_parts = ["python", "-m", "cleveragents"] + command.split()
cmd_parts.extend(["--context-dir", str(context.context_dir)])
# Run the command (it will wait for input but we won't provide it to capture the output)
# We'll use a short timeout to avoid hanging
try:
result = subprocess.run(cmd_parts, input="n\n", capture_output=True, text=True, timeout=5, cwd="/app")
context.cli_result = result
context.cli_stdout = result.stdout
context.cli_stderr = result.stderr
context.cli_returncode = result.returncode
except subprocess.TimeoutExpired as e:
context.cli_stdout = e.stdout.decode() if e.stdout else ""
context.cli_stderr = e.stderr.decode() if e.stderr else ""
context.cli_returncode = -1
# Note: "the command should succeed" and "the command should fail" are already defined in cli_steps.py
@then("the command should be cancelled")
def step_command_should_be_cancelled(context: Context) -> None:
"""Verify the command was cancelled."""
assert "cancelled" in context.cli_stdout.lower() or "cancelled" in context.cli_stderr.lower(), (
f"Command was not cancelled\n" f"stdout: {context.cli_stdout}\n" f"stderr: {context.cli_stderr}"
)
@then('the command should fail with error "{error_text}"')
def step_command_should_fail_with_error(context: Context, error_text: str) -> None:
"""Verify the command failed with specific error message."""
assert context.cli_returncode != 0, (
f"Command succeeded unexpectedly\n" f"stdout: {context.cli_stdout}\n" f"stderr: {context.cli_stderr}"
)
combined_output = context.cli_stdout + context.cli_stderr
assert error_text in combined_output, (
f"Expected error message not found: {error_text}\n"
f"stdout: {context.cli_stdout}\n"
f"stderr: {context.cli_stderr}"
)
@then('the context "{name}" should not exist')
def step_context_should_not_exist(context: Context, name: str) -> None:
"""Verify a context does not exist."""
ctx_dir = context.context_dir / name
assert not ctx_dir.exists(), f"Context '{name}' still exists at {ctx_dir}"
@then('the context "{name}" should still exist')
def step_context_should_still_exist(context: Context, name: str) -> None:
"""Verify a context still exists."""
ctx_dir = context.context_dir / name
assert ctx_dir.exists(), f"Context '{name}' does not exist at {ctx_dir}"
@then("all contexts should be deleted")
def step_all_contexts_deleted(context: Context) -> None:
"""Verify all contexts were deleted."""
# List all subdirectories in the context directory
if context.context_dir.exists():
contexts = [d for d in context.context_dir.iterdir() if d.is_dir()]
assert len(contexts) == 0, f"Found {len(contexts)} contexts still present: {[c.name for c in contexts]}"
@then('the contexts "{names}" should still exist')
def step_contexts_should_still_exist(context: Context, names: str) -> None:
"""Verify specific contexts still exist."""
context_names = [name.strip().strip('"') for name in names.split(",")]
for name in context_names:
ctx_dir = context.context_dir / name
assert ctx_dir.exists(), f"Context '{name}' does not exist at {ctx_dir}"
@then('the output should show "{text}"')
def step_output_should_show(context: Context, text: str) -> None:
"""Verify the output contains specific text."""
combined_output = context.cli_stdout + context.cli_stderr
assert text in combined_output, (
f"Expected text not found in output: {text}\n" f"stdout: {context.cli_stdout}\n" f"stderr: {context.cli_stderr}"
)
@then("the output should show deleted count")
def step_output_shows_deleted_count(context: Context) -> None:
"""Verify the output shows deleted count."""
combined_output = context.cli_stdout + context.cli_stderr
assert "Deleted" in combined_output and "context" in combined_output, (
f"Deleted count not found in output\n" f"stdout: {context.cli_stdout}\n" f"stderr: {context.cli_stderr}"
)
@then("the output should show failed count")
def step_output_shows_failed_count(context: Context) -> None:
"""Verify the output shows failed count."""
combined_output = context.cli_stdout + context.cli_stderr
assert "Failed" in combined_output, (
f"Failed count not found in output\n" f"stdout: {context.cli_stdout}\n" f"stderr: {context.cli_stderr}"
)
# Note: "the output should contain" is already defined in cli_steps.py as "the output should contain '{expected_text}'"
@then("the output should list all contexts before deletion")
def step_output_lists_contexts_before_deletion(context: Context) -> None:
"""Verify the output lists contexts before deletion."""
combined_output = context.cli_stdout + context.cli_stderr
assert "Found" in combined_output and "to delete" in combined_output, (
f"Context list not found in output\n" f"stdout: {context.cli_stdout}\n" f"stderr: {context.cli_stderr}"
)
def after_scenario(context, scenario):
"""Clean up after each scenario."""
# Restore permissions on read-only directories
if hasattr(context, "readonly_dirs"):
for dir_path in context.readonly_dirs:
try:
os.chmod(dir_path, 0o755)
except Exception:
pass
# Clean up temp directory
if hasattr(context, "temp_dir"):
import shutil
try:
shutil.rmtree(context.temp_dir)
except Exception:
pass
@@ -0,0 +1,318 @@
*** Settings ***
Documentation Integration tests for context delete with --all and --yes flags
Library Process
Library OperatingSystem
Library String
Library DateTime
Suite Setup Setup Test Environment
Suite Teardown Cleanup Test Environment
*** Variables ***
${SIMPLE_CONFIG} tests/fixtures/simple_echo_config.yaml
${CONTEXT_DIR} ${TEMPDIR}/test_contexts_delete_all_yes
${UNIQUE_ID} ${EMPTY}
${TEMP} ${EMPTY}
*** Test Cases ***
Test Delete Single Context With Yes Flag
[Documentation] Test context delete with --yes bypasses confirmation
${context_name} = Set Variable delete_yes_${UNIQUE_ID}
# Create context
Run Process python -m cleveragents run
... -c ${SIMPLE_CONFIG}
... --context ${context_name}
... --context-dir ${CONTEXT_DIR}
... --unsafe
... -p "test message"
Directory Should Exist ${CONTEXT_DIR}/${context_name}
# Delete it with --yes flag
${result} = Run Process python -m cleveragents context delete
... ${context_name}
... --context-dir ${CONTEXT_DIR}
... --yes
Should Be Equal As Integers ${result.rc} 0
Directory Should Not Exist ${CONTEXT_DIR}/${context_name}
Should Contain ${result.stdout} deleted
Test Delete Single Context With Short Yes Flag
[Documentation] Test context delete with -y shorthand flag
${context_name} = Set Variable delete_short_${UNIQUE_ID}
# Create context
Run Process python -m cleveragents run
... -c ${SIMPLE_CONFIG}
... --context ${context_name}
... --context-dir ${CONTEXT_DIR}
... --unsafe
... -p "test message"
Directory Should Exist ${CONTEXT_DIR}/${context_name}
# Delete it with -y flag
${result} = Run Process python -m cleveragents context delete
... ${context_name}
... --context-dir ${CONTEXT_DIR}
... -y
Should Be Equal As Integers ${result.rc} 0
Directory Should Not Exist ${CONTEXT_DIR}/${context_name}
Test Delete Single Context With Confirmation Accept
[Documentation] Test context delete with confirmation accepted
${context_name} = Set Variable delete_confirm_${UNIQUE_ID}
# Create context
Run Process python -m cleveragents run
... -c ${SIMPLE_CONFIG}
... --context ${context_name}
... --context-dir ${CONTEXT_DIR}
... --unsafe
... -p "test message"
Directory Should Exist ${CONTEXT_DIR}/${context_name}
# Delete with confirmation (answer 'y')
${result} = Run Process python -m cleveragents context delete
... ${context_name}
... --context-dir ${CONTEXT_DIR}
... stdin=y\n
Should Be Equal As Integers ${result.rc} 0
Directory Should Not Exist ${CONTEXT_DIR}/${context_name}
Test Delete Single Context With Confirmation Reject
[Documentation] Test context delete with confirmation rejected
${context_name} = Set Variable delete_reject_${UNIQUE_ID}
# Create context
Run Process python -m cleveragents run
... -c ${SIMPLE_CONFIG}
... --context ${context_name}
... --context-dir ${CONTEXT_DIR}
... --unsafe
... -p "test message"
Directory Should Exist ${CONTEXT_DIR}/${context_name}
# Delete with confirmation rejected (answer 'n')
${result} = Run Process python -m cleveragents context delete
... ${context_name}
... --context-dir ${CONTEXT_DIR}
... stdin=n\n
Should Be Equal As Integers ${result.rc} 0
Directory Should Exist ${CONTEXT_DIR}/${context_name}
Should Contain ${result.stdout} cancelled
Test Delete All Contexts With All And Yes Flags
[Documentation] Test delete all contexts with --all --yes
[Setup] Empty Directory ${CONTEXT_DIR}
${ctx1} = Set Variable all_ctx1_${UNIQUE_ID}
${ctx2} = Set Variable all_ctx2_${UNIQUE_ID}
${ctx3} = Set Variable all_ctx3_${UNIQUE_ID}
# Create multiple contexts
Run Process python -m cleveragents run
... -c ${SIMPLE_CONFIG}
... --context ${ctx1}
... --context-dir ${CONTEXT_DIR}
... --unsafe
... -p "test"
Run Process python -m cleveragents run
... -c ${SIMPLE_CONFIG}
... --context ${ctx2}
... --context-dir ${CONTEXT_DIR}
... --unsafe
... -p "test"
Run Process python -m cleveragents run
... -c ${SIMPLE_CONFIG}
... --context ${ctx3}
... --context-dir ${CONTEXT_DIR}
... --unsafe
... -p "test"
Directory Should Exist ${CONTEXT_DIR}/${ctx1}
Directory Should Exist ${CONTEXT_DIR}/${ctx2}
Directory Should Exist ${CONTEXT_DIR}/${ctx3}
# Delete all with --all --yes
${result} = Run Process python -m cleveragents context delete
... --all
... --yes
... --context-dir ${CONTEXT_DIR}
Should Be Equal As Integers ${result.rc} 0
Directory Should Not Exist ${CONTEXT_DIR}/${ctx1}
Directory Should Not Exist ${CONTEXT_DIR}/${ctx2}
Directory Should Not Exist ${CONTEXT_DIR}/${ctx3}
Should Contain ${result.stdout} Deleted 3 context
Test Delete All With Confirmation Accept
[Documentation] Test delete all with confirmation accepted
[Setup] Empty Directory ${CONTEXT_DIR}
${ctx1} = Set Variable all_confirm1_${UNIQUE_ID}
${ctx2} = Set Variable all_confirm2_${UNIQUE_ID}
# Create contexts
Run Process python -m cleveragents run
... -c ${SIMPLE_CONFIG}
... --context ${ctx1}
... --context-dir ${CONTEXT_DIR}
... --unsafe
... -p "test"
Run Process python -m cleveragents run
... -c ${SIMPLE_CONFIG}
... --context ${ctx2}
... --context-dir ${CONTEXT_DIR}
... --unsafe
... -p "test"
# Delete all with confirmation
${result} = Run Process python -m cleveragents context delete
... --all
... --context-dir ${CONTEXT_DIR}
... stdin=y\n
Should Be Equal As Integers ${result.rc} 0
Directory Should Not Exist ${CONTEXT_DIR}/${ctx1}
Directory Should Not Exist ${CONTEXT_DIR}/${ctx2}
Should Contain ${result.stdout} Found
Should Contain ${result.stdout} to delete
Test Delete All With Confirmation Reject
[Documentation] Test delete all with confirmation rejected
[Setup] Empty Directory ${CONTEXT_DIR}
${ctx1} = Set Variable all_reject1_${UNIQUE_ID}
${ctx2} = Set Variable all_reject2_${UNIQUE_ID}
# Create contexts
Run Process python -m cleveragents run
... -c ${SIMPLE_CONFIG}
... --context ${ctx1}
... --context-dir ${CONTEXT_DIR}
... --unsafe
... -p "test"
Run Process python -m cleveragents run
... -c ${SIMPLE_CONFIG}
... --context ${ctx2}
... --context-dir ${CONTEXT_DIR}
... --unsafe
... -p "test"
# Delete all with confirmation rejected
${result} = Run Process python -m cleveragents context delete
... --all
... --context-dir ${CONTEXT_DIR}
... stdin=n\n
Should Be Equal As Integers ${result.rc} 0
Directory Should Exist ${CONTEXT_DIR}/${ctx1}
Directory Should Exist ${CONTEXT_DIR}/${ctx2}
Should Contain ${result.stdout} cancelled
Test Error When Both Name And All Provided
[Documentation] Test error when both NAME and --all are provided
${result} = Run Process python -m cleveragents context delete
... test_context
... --all
... --context-dir ${CONTEXT_DIR}
Should Not Be Equal As Integers ${result.rc} 0
Should Contain Any ${result.stderr} ${result.stdout} Cannot specify NAME when using --all
Test Error When Neither Name Nor All Provided
[Documentation] Test error when neither NAME nor --all is provided
${result} = Run Process python -m cleveragents context delete
... --context-dir ${CONTEXT_DIR}
Should Not Be Equal As Integers ${result.rc} 0
Should Contain Any ${result.stderr} ${result.stdout} Must specify NAME or use --all
Test Delete All When No Contexts Exist
[Documentation] Test delete all when directory is empty
# Ensure directory is empty
Empty Directory ${CONTEXT_DIR}
${result} = Run Process python -m cleveragents context delete
... --all
... --yes
... --context-dir ${CONTEXT_DIR}
Should Be Equal As Integers ${result.rc} 0
Should Contain ${result.stdout} No contexts found
Test Delete Non Existent Context
[Documentation] Test deleting a context that doesn't exist
${result} = Run Process python -m cleveragents context delete
... non_existent_context_${UNIQUE_ID}
... --yes
... --context-dir ${CONTEXT_DIR}
Should Not Be Equal As Integers ${result.rc} 0
Should Contain Any ${result.stderr} ${result.stdout} does not exist
Test Delete All Shows Context List Before Deletion
[Documentation] Test that --all shows context list before confirmation
[Setup] Empty Directory ${CONTEXT_DIR}
${ctx1} = Set Variable list_ctx1_${UNIQUE_ID}
${ctx2} = Set Variable list_ctx2_${UNIQUE_ID}
${ctx3} = Set Variable list_ctx3_${UNIQUE_ID}
# Create contexts
Run Process python -m cleveragents run
... -c ${SIMPLE_CONFIG}
... --context ${ctx1}
... --context-dir ${CONTEXT_DIR}
... --unsafe
... -p "test"
Run Process python -m cleveragents run
... -c ${SIMPLE_CONFIG}
... --context ${ctx2}
... --context-dir ${CONTEXT_DIR}
... --unsafe
... -p "test"
Run Process python -m cleveragents run
... -c ${SIMPLE_CONFIG}
... --context ${ctx3}
... --context-dir ${CONTEXT_DIR}
... --unsafe
... -p "test"
# Delete all with confirmation to see list
${result} = Run Process python -m cleveragents context delete
... --all
... --context-dir ${CONTEXT_DIR}
... stdin=n\n
Should Contain ${result.stdout} Found 3 context
Should Contain ${result.stdout} ${ctx1}
Should Contain ${result.stdout} ${ctx2}
Should Contain ${result.stdout} ${ctx3}
*** Keywords ***
Setup Test Environment
${timestamp} = Get Current Date result_format=%Y%m%d_%H%M%S
${random} = Evaluate random.randint(1000, 9999) modules=random
Set Suite Variable ${UNIQUE_ID} ${timestamp}_${random}
Set Suite Variable ${TEMP} ${TEMPDIR}/ca_delete_test_${UNIQUE_ID}
Set Suite Variable ${CONTEXT_DIR} ${TEMP}/contexts
Create Directory ${TEMP}
Create Directory ${CONTEXT_DIR}
Cleanup Test Environment
Run Keyword And Ignore Error Remove Directory ${TEMP} recursive=True
Should Contain Any
[Arguments] ${text1} ${text2} ${expected}
${combined} = Set Variable ${text1}${text2}
Should Contain ${combined} ${expected}