Files
temp/tests/features/steps/unit_tool_command_processing_steps.py
T

193 lines
10 KiB
Python

"""Step definitions for tool command processing unit tests."""
import json
import re
from behave import given, then, when
@given("a content with simple file_read tool command")
def step_given_simple_file_read_content(context):
"""Set up content with a simple file_read command."""
context.content = """
Some text before
[TOOL_EXECUTE:file_read]
{"file": "simple.txt"}
[/TOOL_EXECUTE]
Some text after
"""
@given("a content with nested JSON file_write tool command")
def step_given_nested_json_content(context):
"""Set up content with nested JSON in file_write command."""
context.content = """
[TOOL_EXECUTE:file_write]
{"file": "analysis.json", "content": "{\\"document_info\\": {\\"analysis_date\\": \\"2025-10-03\\", \\"total_confidence\\": 0.91}, \\"parties\\": [{\\"name\\": \\"TechCorp\\", \\"confidence\\": 0.95}]}"}
[/TOOL_EXECUTE]
"""
@given("a content with multiple tool commands")
def step_given_multiple_commands(context):
"""Set up content with multiple tool commands."""
context.content = """
First we load:
[TOOL_EXECUTE:file_read]
{"file": "contract.txt"}
[/TOOL_EXECUTE]
Then we save:
[TOOL_EXECUTE:file_write]
{"file": "output.json", "content": "{\\"key\\": \\"value\\"}"}
[/TOOL_EXECUTE]
"""
@given("a content with complex legal contract analyzer JSON")
def step_given_complex_json_content(context):
"""Set up content with complex nested JSON from legal contract analyzer."""
context.content = """
[TOOL_EXECUTE:file_write]
{"file": "contract_analysis.json", "content": "{\\"document_info\\": {\\"analysis_date\\": \\"2025-10-03\\", \\"document_type\\": \\"service_agreement\\", \\"total_confidence\\": 0.91, \\"analysis_version\\": \\"1.0\\"}, \\"parties\\": [{\\"name\\": \\"TechCorp Solutions Inc.\\", \\"type\\": \\"company\\", \\"role\\": \\"provider\\", \\"contact_info\\": \\"123 Tech Street, San Francisco, CA 94105\\", \\"representative\\": {\\"name\\": \\"John Smith\\", \\"title\\": \\"Chief Technology Officer\\"}, \\"confidence\\": 0.95}, {\\"name\\": \\"Global Enterprises LLC\\", \\"type\\": \\"company\\", \\"role\\": \\"client\\", \\"contact_info\\": \\"456 Business Ave, Los Angeles, CA 90001\\", \\"representative\\": {\\"name\\": \\"Sarah Johnson\\", \\"title\\": \\"Chief Executive Officer\\"}, \\"confidence\\": 0.95}], \\"dates\\": {\\"signing_date\\": \\"2024-01-15\\", \\"effective_date\\": \\"2024-01-15\\", \\"expiration_date\\": \\"2026-01-15\\", \\"payment_due_days\\": 30, \\"termination_notice_days\\": 90, \\"confidence\\": 0.98}, \\"financial_terms\\": {\\"total_value\\": {\\"amount\\": 120000, \\"currency\\": \\"USD\\", \\"period\\": \\"24 months\\", \\"confidence\\": 1.0}, \\"payment_schedule\\": [{\\"amount\\": 5000, \\"frequency\\": \\"monthly\\", \\"due_date_offset\\": 30, \\"description\\": \\"Monthly service fee\\", \\"confidence\\": 1.0}], \\"penalties_fees\\": [{\\"type\\": \\"late_payment_penalty\\", \\"amount\\": \\"1.5% per month\\", \\"condition\\": \\"Late payment\\", \\"confidence\\": 1.0}], \\"overall_confidence\\": 0.98}, \\"obligations\\": {\\"party_obligations\\": [{\\"party\\": \\"TechCorp Solutions Inc.\\", \\"deliverables\\": [\\"Virtual server hosting\\", \\"Data storage and backup services\\", \\"Network infrastructure management\\", \\"24/7 technical support\\"], \\"performance_standards\\": [\\"99.9% uptime guarantee\\"], \\"confidence\\": 0.95}], \\"overall_confidence\\": 0.93}, \\"legal_terms\\": {\\"governing_law\\": \\"State of California\\", \\"termination_conditions\\": [\\"90 days written notice by either party\\", \\"Immediate termination for non-payment or material breach\\"], \\"liability_clauses\\": [\\"Total liability limited to 12 months of payments\\"], \\"confidentiality\\": \\"yes\\", \\"confidence\\": 0.92}, \\"risk_assessment\\": {\\"high_risk_terms\\": [\\"Limited liability cap may be insufficient\\", \\"No data privacy clauses\\"], \\"missing_clauses\\": [\\"Force Majeure\\", \\"Dispute Resolution\\", \\"Data Protection\\", \\"IP Ownership\\"], \\"ambiguous_language\\": [\\"Proprietary information not defined\\", \\"Technical specifications unclear\\"], \\"overall_risk_score\\": 0.65, \\"risk_level\\": \\"Medium-High\\", \\"confidence\\": 0.87}, \\"extraction_summary\\": {\\"total_sections_analyzed\\": 6, \\"successfully_extracted_fields\\": 18, \\"failed_extractions\\": [], \\"overall_confidence\\": 0.91}}"}
[/TOOL_EXECUTE]
"""
@when("I extract the tool command using regex")
def step_when_extract_single_command(context):
"""Extract a single tool command using regex pattern."""
pattern = r"\[TOOL_EXECUTE:(\w+)\]\s*(.*?)\s*\[/TOOL_EXECUTE\]"
matches = list(re.finditer(pattern, context.content, re.DOTALL))
context.matches = matches
if len(matches) > 0:
context.tool_name = matches[0].group(1)
params_str = matches[0].group(2).strip()
context.params = json.loads(params_str)
# Try to parse nested JSON if it exists
if "content" in context.params and isinstance(context.params["content"], str):
try:
context.nested_json = json.loads(context.params["content"])
except json.JSONDecodeError:
context.nested_json = None
@when("I extract all tool commands using regex")
def step_when_extract_all_commands(context):
"""Extract all tool commands using regex pattern."""
pattern = r"\[TOOL_EXECUTE:(\w+)\]\s*(.*?)\s*\[/TOOL_EXECUTE\]"
context.matches = list(re.finditer(pattern, context.content, re.DOTALL))
@then('the tool name should be "{expected_name}"')
def step_then_check_tool_name(context, expected_name):
"""Verify the tool name matches expectation."""
assert context.tool_name == expected_name, f"Expected '{expected_name}', got '{context.tool_name}'"
@then('the parameters should contain file "{expected_file}"')
def step_then_check_file_parameter(context, expected_file):
"""Verify the file parameter matches expectation."""
assert "file" in context.params, "Parameters should contain 'file' key"
assert context.params["file"] == expected_file, f"Expected file '{expected_file}', got '{context.params['file']}'"
@then("the nested JSON content should be parseable")
def step_then_nested_json_parseable(context):
"""Verify nested JSON can be parsed."""
assert context.nested_json is not None, "Nested JSON should be parseable"
@then('the nested JSON should contain document_info with analysis_date "{expected_date}"')
def step_then_check_analysis_date(context, expected_date):
"""Verify nested JSON contains expected analysis_date."""
assert "document_info" in context.nested_json, "Nested JSON should contain document_info"
assert context.nested_json["document_info"]["analysis_date"] == expected_date
@then('the nested JSON should contain parties with name "{expected_name}"')
def step_then_check_party_name(context, expected_name):
"""Verify nested JSON contains expected party name."""
assert "parties" in context.nested_json, "Nested JSON should contain parties"
assert len(context.nested_json["parties"]) > 0, "Parties array should not be empty"
assert context.nested_json["parties"][0]["name"] == expected_name
@then("I should find {count:d} tool commands")
def step_then_check_command_count(context, count):
"""Verify the number of tool commands found."""
assert len(context.matches) == count, f"Expected {count} commands, found {len(context.matches)}"
@then('the first tool command should be "{expected_name}"')
def step_then_check_first_command(context, expected_name):
"""Verify the first tool command name."""
assert len(context.matches) > 0, "Should have at least one command"
first_name = context.matches[0].group(1)
assert first_name == expected_name, f"Expected '{expected_name}', got '{first_name}'"
@then('the second tool command should be "{expected_name}"')
def step_then_check_second_command(context, expected_name):
"""Verify the second tool command name."""
assert len(context.matches) > 1, "Should have at least two commands"
second_name = context.matches[1].group(1)
assert second_name == expected_name, f"Expected '{expected_name}', got '{second_name}'"
@then("the complex nested JSON should be parseable")
def step_then_complex_json_parseable(context):
"""Verify complex nested JSON can be parsed."""
assert context.nested_json is not None, "Complex nested JSON should be parseable"
@then("the complex nested JSON should contain all required sections")
def step_then_check_all_sections(context):
"""Verify all required sections exist in complex JSON."""
required_sections = [
"document_info",
"parties",
"dates",
"financial_terms",
"obligations",
"legal_terms",
"risk_assessment",
"extraction_summary",
]
for section in required_sections:
assert section in context.nested_json, f"Missing required section: {section}"
@then('the complex nested JSON document_info analysis_date should be "{expected_date}"')
def step_then_check_complex_analysis_date(context, expected_date):
"""Verify complex JSON analysis_date."""
assert context.nested_json["document_info"]["analysis_date"] == expected_date
@then('the complex nested JSON first party name should be "{expected_name}"')
def step_then_check_first_party(context, expected_name):
"""Verify first party name in complex JSON."""
assert context.nested_json["parties"][0]["name"] == expected_name
@then('the complex nested JSON second party name should be "{expected_name}"')
def step_then_check_second_party(context, expected_name):
"""Verify second party name in complex JSON."""
assert context.nested_json["parties"][1]["name"] == expected_name
@then("the complex nested JSON financial total_value amount should be {expected_amount:d}")
def step_then_check_financial_amount(context, expected_amount):
"""Verify financial amount in complex JSON."""
actual_amount = context.nested_json["financial_terms"]["total_value"]["amount"]
assert actual_amount == expected_amount, f"Expected {expected_amount}, got {actual_amount}"
@then("the complex nested JSON should have {count:d} missing_clauses")
def step_then_check_missing_clauses_count(context, count):
"""Verify number of missing clauses in complex JSON."""
missing_clauses = context.nested_json["risk_assessment"]["missing_clauses"]
assert len(missing_clauses) == count, f"Expected {count} missing clauses, found {len(missing_clauses)}"