|
| 1 | +import os |
| 2 | +import re |
| 3 | +from unittest.mock import patch |
| 4 | + |
| 5 | +import pytest |
| 6 | +from strands import Agent |
| 7 | +from strands_tools import editor, file_read, file_write |
| 8 | + |
| 9 | + |
| 10 | +@pytest.fixture |
| 11 | +def agent(): |
| 12 | + """Agent with file read, write, and editor tools.""" |
| 13 | + return Agent(tools=[file_write, file_read, editor]) |
| 14 | + |
| 15 | + |
| 16 | +@pytest.fixture(autouse=True) |
| 17 | +def bypass_tool_consent_env(): |
| 18 | + with patch.dict(os.environ, {"BYPASS_TOOL_CONSENT": "true"}): |
| 19 | + yield |
| 20 | + |
| 21 | + |
| 22 | +def extract_code_content(response): |
| 23 | + """Helper function to extract code block content from LLM output.""" |
| 24 | + match = re.search(r"```(?:[a-zA-Z]*\n)?(.*?)```", str(response), re.DOTALL) |
| 25 | + return match.group(1) if match else str(response) |
| 26 | + |
| 27 | + |
| 28 | +def test_semantic_write_read_edit_workflow(agent, tmp_path): |
| 29 | + """Test complete semantic workflow: write -> read -> edit -> verify.""" |
| 30 | + file_path = tmp_path / "semantic_test.txt" |
| 31 | + initial_content = "Hello world from integration test!" |
| 32 | + |
| 33 | + # 1. Write file |
| 34 | + write_response = agent(f"Write '{initial_content}' to file `{file_path}`") |
| 35 | + assert "success" in str(write_response).lower() or "written" in str(write_response).lower() |
| 36 | + |
| 37 | + # 2. Read file back using both agent & reading file directly |
| 38 | + read_response = agent(f"Read the contents of file `{file_path}`") |
| 39 | + content = extract_code_content(read_response) |
| 40 | + assert initial_content in content |
| 41 | + |
| 42 | + with open(file_path, "r") as f: |
| 43 | + raw_content = f.read() |
| 44 | + assert initial_content in raw_content |
| 45 | + |
| 46 | + # 3. Replace text |
| 47 | + edit_response = agent(f"In file `{file_path}`, replace 'Hello' with 'Hi'") |
| 48 | + assert "success" in str(edit_response).lower() or "replaced" in str(edit_response).lower() |
| 49 | + |
| 50 | + # 4. Verify |
| 51 | + verify_response = agent(f"Show me the contents of `{file_path}`") |
| 52 | + final_content = extract_code_content(verify_response) |
| 53 | + assert "Hi world" in final_content |
| 54 | + assert "Hello" not in final_content |
| 55 | + |
| 56 | + |
| 57 | +def test_semantic_python_file_creation(agent, tmp_path): |
| 58 | + """Test creating and modifying Python code semantically.""" |
| 59 | + file_path = tmp_path / "test_script.py" |
| 60 | + |
| 61 | + # 1. Create Python file |
| 62 | + create_response = agent(f"Create a Python file at `{file_path}` with a function that prints 'Hello World'") |
| 63 | + assert "success" in str(create_response).lower() or "created" in str(create_response).lower() |
| 64 | + |
| 65 | + # 2. Read and verify |
| 66 | + read_response = agent(f"Show me the Python code in `{file_path}`") |
| 67 | + content = str(read_response) |
| 68 | + assert "def" in content and "print" in content and "Hello World" in content |
| 69 | + |
| 70 | + # 3. Modify the function |
| 71 | + modify_response = agent(f"In `{file_path}`, change the print statement to say 'Hi there!' instead") |
| 72 | + semantic_success = any( |
| 73 | + phrase in str(modify_response).lower() |
| 74 | + for phrase in [ |
| 75 | + "file has been updated", |
| 76 | + "now prints 'hi there!'", |
| 77 | + "updated successfully", |
| 78 | + "replacement was successful", |
| 79 | + "print statement to say 'hi there!'", |
| 80 | + "prints 'Hello World'", |
| 81 | + ] |
| 82 | + ) |
| 83 | + assert semantic_success, str(modify_response) |
| 84 | + |
| 85 | + # 4. Verify modification |
| 86 | + final_response = agent(f"Read `{file_path}` and show me the code") |
| 87 | + final_content = str(final_response) |
| 88 | + assert "Hi there!" in final_content |
| 89 | + |
| 90 | + |
| 91 | +def test_semantic_search_and_replace(agent, tmp_path): |
| 92 | + """Test semantic search and replace operations.""" |
| 93 | + file_path = tmp_path / "config.txt" |
| 94 | + |
| 95 | + # 1. Create config file |
| 96 | + agent(f"Create a config file at `{file_path}` with settings: debug=true, port=8080, host=localhost") |
| 97 | + |
| 98 | + # 2. Change a specific setting |
| 99 | + agent(f"In `{file_path}`, change the port from 8080 to 3000") |
| 100 | + |
| 101 | + # 3. Verify the change |
| 102 | + verify_response = agent(f"What is the port setting in `{file_path}`?") |
| 103 | + assert "3000" in str(verify_response) |
| 104 | + |
| 105 | + # 4. Final check |
| 106 | + final_response = agent(f"Show me all settings in `{file_path}`") |
| 107 | + final_content = str(final_response) |
| 108 | + assert "3000" in final_content |
0 commit comments