mirror of
https://gitee.com/wanwujie/deer-flow
synced 2026-04-18 12:04:45 +08:00
feat: lite deep researcher implementation
This commit is contained in:
44
tests/integration/test_bash_tool.py
Normal file
44
tests/integration/test_bash_tool.py
Normal file
@@ -0,0 +1,44 @@
|
||||
import unittest
|
||||
import subprocess
|
||||
from unittest.mock import patch
|
||||
from src.tools.bash_tool import bash_tool
|
||||
|
||||
|
||||
class TestBashTool(unittest.TestCase):
|
||||
def test_successful_command(self):
|
||||
"""Test bash tool with a successful command execution"""
|
||||
result = bash_tool.invoke("echo 'Hello World'")
|
||||
self.assertEqual(result.strip(), "Hello World")
|
||||
|
||||
@patch("subprocess.run")
|
||||
def test_command_with_error(self, mock_run):
|
||||
"""Test bash tool when command fails"""
|
||||
# Configure mock to raise CalledProcessError
|
||||
mock_run.side_effect = subprocess.CalledProcessError(
|
||||
returncode=1, cmd="invalid_command", output="", stderr="Command not found"
|
||||
)
|
||||
|
||||
result = bash_tool.invoke("invalid_command")
|
||||
self.assertIn("Command failed with exit code 1", result)
|
||||
self.assertIn("Command not found", result)
|
||||
|
||||
@patch("subprocess.run")
|
||||
def test_command_with_exception(self, mock_run):
|
||||
"""Test bash tool when an unexpected exception occurs"""
|
||||
# Configure mock to raise a generic exception
|
||||
mock_run.side_effect = Exception("Unexpected error")
|
||||
|
||||
result = bash_tool.invoke("some_command")
|
||||
self.assertIn("Error executing command: Unexpected error", result)
|
||||
|
||||
def test_command_with_output(self):
|
||||
"""Test bash tool with a command that produces output"""
|
||||
# Create a temporary file and write to it
|
||||
result = bash_tool.invoke(
|
||||
"echo 'test content' > test_file.txt && cat test_file.txt && rm test_file.txt"
|
||||
)
|
||||
self.assertEqual(result.strip(), "test content")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
27
tests/integration/test_crawler.py
Normal file
27
tests/integration/test_crawler.py
Normal file
@@ -0,0 +1,27 @@
|
||||
import pytest
|
||||
from src.crawler import Crawler
|
||||
|
||||
|
||||
def test_crawler_initialization():
|
||||
"""Test that crawler can be properly initialized."""
|
||||
crawler = Crawler()
|
||||
assert isinstance(crawler, Crawler)
|
||||
|
||||
|
||||
def test_crawler_crawl_valid_url():
|
||||
"""Test crawling with a valid URL."""
|
||||
crawler = Crawler()
|
||||
test_url = "https://finance.sina.com.cn/stock/relnews/us/2024-08-15/doc-incitsya6536375.shtml"
|
||||
result = crawler.crawl(test_url)
|
||||
assert result is not None
|
||||
assert hasattr(result, "to_markdown")
|
||||
|
||||
|
||||
def test_crawler_markdown_output():
|
||||
"""Test that crawler output can be converted to markdown."""
|
||||
crawler = Crawler()
|
||||
test_url = "https://finance.sina.com.cn/stock/relnews/us/2024-08-15/doc-incitsya6536375.shtml"
|
||||
result = crawler.crawl(test_url)
|
||||
markdown = result.to_markdown()
|
||||
assert isinstance(markdown, str)
|
||||
assert len(markdown) > 0
|
||||
57
tests/integration/test_python_repl_tool.py
Normal file
57
tests/integration/test_python_repl_tool.py
Normal file
@@ -0,0 +1,57 @@
|
||||
import pytest
|
||||
from src.tools.python_repl import python_repl_tool
|
||||
|
||||
|
||||
def test_python_repl_tool_success():
|
||||
code = "print(1 + 1)"
|
||||
result = python_repl_tool(code)
|
||||
assert "Successfully executed" in result
|
||||
assert "Stdout: 2" in result
|
||||
|
||||
|
||||
def test_python_repl_tool_syntax_error():
|
||||
code = "print(1 + )"
|
||||
result = python_repl_tool(code)
|
||||
assert "Error executing code:" in result
|
||||
assert code in result
|
||||
assert "SyntaxError" in result
|
||||
|
||||
|
||||
def test_python_repl_tool_runtime_error():
|
||||
code = "print(1 / 0)"
|
||||
result = python_repl_tool(code)
|
||||
assert "Error executing code:" in result
|
||||
assert code in result
|
||||
assert "ZeroDivisionError" in result
|
||||
|
||||
|
||||
def test_python_repl_tool_name_error():
|
||||
code = "print(undefined_variable)"
|
||||
result = python_repl_tool(code)
|
||||
assert "Error executing code:" in result
|
||||
assert code in result
|
||||
assert "NameError" in result
|
||||
|
||||
|
||||
def test_python_repl_tool_type_error():
|
||||
code = "'2' + 2"
|
||||
result = python_repl_tool(code)
|
||||
assert "Error executing code:" in result
|
||||
assert code in result
|
||||
assert "TypeError" in result
|
||||
|
||||
|
||||
def test_python_repl_tool_import_error():
|
||||
code = "from nonexistent_module import something"
|
||||
result = python_repl_tool(code)
|
||||
assert "Error executing code:" in result
|
||||
assert code in result
|
||||
assert "ModuleNotFoundError" in result
|
||||
|
||||
|
||||
def test_python_repl_tool_exception():
|
||||
code = "raise Exception('Test')"
|
||||
result = python_repl_tool(code)
|
||||
assert "Error executing code:" in result
|
||||
assert code in result
|
||||
assert "Exception" in result
|
||||
105
tests/integration/test_template.py
Normal file
105
tests/integration/test_template.py
Normal file
@@ -0,0 +1,105 @@
|
||||
import pytest
|
||||
from src.prompts.template import get_prompt_template, apply_prompt_template
|
||||
|
||||
|
||||
def test_get_prompt_template_success():
|
||||
"""Test successful template loading"""
|
||||
template = get_prompt_template("coder")
|
||||
assert template is not None
|
||||
assert isinstance(template, str)
|
||||
assert len(template) > 0
|
||||
|
||||
|
||||
def test_get_prompt_template_not_found():
|
||||
"""Test handling of non-existent template"""
|
||||
with pytest.raises(ValueError) as exc_info:
|
||||
get_prompt_template("non_existent_template")
|
||||
assert "Error loading template" in str(exc_info.value)
|
||||
|
||||
|
||||
def test_apply_prompt_template():
|
||||
"""Test template variable substitution"""
|
||||
test_state = {
|
||||
"messages": [{"role": "user", "content": "test message"}],
|
||||
"task": "test task",
|
||||
"workspace_context": "test context",
|
||||
}
|
||||
|
||||
messages = apply_prompt_template("coder", test_state)
|
||||
|
||||
assert isinstance(messages, list)
|
||||
assert len(messages) > 1
|
||||
assert messages[0]["role"] == "system"
|
||||
assert "CURRENT_TIME" in messages[0]["content"]
|
||||
assert messages[1]["role"] == "user"
|
||||
assert messages[1]["content"] == "test message"
|
||||
|
||||
|
||||
def test_apply_prompt_template_empty_messages():
|
||||
"""Test template with empty messages list"""
|
||||
test_state = {
|
||||
"messages": [],
|
||||
"task": "test task",
|
||||
"workspace_context": "test context",
|
||||
}
|
||||
|
||||
messages = apply_prompt_template("coder", test_state)
|
||||
assert len(messages) == 1 # Only system message
|
||||
assert messages[0]["role"] == "system"
|
||||
|
||||
|
||||
def test_apply_prompt_template_multiple_messages():
|
||||
"""Test template with multiple messages"""
|
||||
test_state = {
|
||||
"messages": [
|
||||
{"role": "user", "content": "first message"},
|
||||
{"role": "assistant", "content": "response"},
|
||||
{"role": "user", "content": "second message"},
|
||||
],
|
||||
"task": "test task",
|
||||
"workspace_context": "test context",
|
||||
}
|
||||
|
||||
messages = apply_prompt_template("coder", test_state)
|
||||
assert len(messages) == 4 # system + 3 messages
|
||||
assert messages[0]["role"] == "system"
|
||||
assert all(m["role"] in ["system", "user", "assistant"] for m in messages)
|
||||
|
||||
|
||||
def test_apply_prompt_template_with_special_chars():
|
||||
"""Test template with special characters in variables"""
|
||||
test_state = {
|
||||
"messages": [{"role": "user", "content": "test\nmessage\"with'special{chars}"}],
|
||||
"task": "task with $pecial ch@rs",
|
||||
"workspace_context": "<html>context</html>",
|
||||
}
|
||||
|
||||
messages = apply_prompt_template("coder", test_state)
|
||||
assert messages[1]["content"] == "test\nmessage\"with'special{chars}"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("prompt_name", ["coder", "coder", "coordinator", "planner"])
|
||||
def test_multiple_template_types(prompt_name):
|
||||
"""Test loading different types of templates"""
|
||||
template = get_prompt_template(prompt_name)
|
||||
assert template is not None
|
||||
assert isinstance(template, str)
|
||||
assert len(template) > 0
|
||||
|
||||
|
||||
def test_current_time_format():
|
||||
"""Test the format of CURRENT_TIME in rendered template"""
|
||||
test_state = {
|
||||
"messages": [{"role": "user", "content": "test"}],
|
||||
"task": "test",
|
||||
"workspace_context": "test",
|
||||
}
|
||||
|
||||
messages = apply_prompt_template("coder", test_state)
|
||||
system_content = messages[0]["content"]
|
||||
|
||||
# Time format should be like: Mon Jan 01 2024 12:34:56 +0000
|
||||
time_format = r"\w{3} \w{3} \d{2} \d{4} \d{2}:\d{2}:\d{2}"
|
||||
assert any(
|
||||
line.strip().startswith("CURRENT_TIME:") for line in system_content.split("\n")
|
||||
)
|
||||
Reference in New Issue
Block a user