1+ #!/usr/bin/env python3
2+
3+ import unittest
4+ import os
5+ from unittest .mock import patch , MagicMock
6+ from pathlib import Path
7+ import sys
8+
9+ # Add the parent directory to the Python path so we can import the module
10+ sys .path .append (os .path .dirname (os .path .dirname (os .path .abspath (__file__ ))))
11+ from tools .plan_exec_llm import load_environment , read_plan_status , read_file_content , create_llm_client , query_llm
12+
13+ class TestPlanExecLLM (unittest .TestCase ):
14+ def setUp (self ):
15+ """Set up test fixtures"""
16+ self .test_env_content = """
17+ OPENAI_API_KEY=test_key
18+ """
19+ self .test_plan_content = """
20+ # Multi-Agent Scratchpad
21+ Test content
22+ """
23+ # Create temporary test files
24+ with open ('.env.test' , 'w' ) as f :
25+ f .write (self .test_env_content )
26+ with open ('.cursorrules.test' , 'w' ) as f :
27+ f .write (self .test_plan_content )
28+
29+ def tearDown (self ):
30+ """Clean up test fixtures"""
31+ # Remove temporary test files
32+ for file in ['.env.test' , '.cursorrules.test' ]:
33+ if os .path .exists (file ):
34+ os .remove (file )
35+
36+ @patch ('tools.plan_exec_llm.load_dotenv' )
37+ def test_load_environment (self , mock_load_dotenv ):
38+ """Test environment loading"""
39+ load_environment ()
40+ mock_load_dotenv .assert_called ()
41+
42+ def test_read_plan_status (self ):
43+ """Test reading plan status"""
44+ with patch ('tools.plan_exec_llm.STATUS_FILE' , '.cursorrules.test' ):
45+ content = read_plan_status ()
46+ self .assertIn ('# Multi-Agent Scratchpad' , content )
47+ self .assertIn ('Test content' , content )
48+
49+ def test_read_file_content (self ):
50+ """Test reading file content"""
51+ # Test with existing file
52+ content = read_file_content ('.env.test' )
53+ self .assertIn ('OPENAI_API_KEY=test_key' , content )
54+
55+ # Test with non-existent file
56+ content = read_file_content ('nonexistent_file.txt' )
57+ self .assertIsNone (content )
58+
59+ @patch .dict (os .environ , {'OPENAI_API_KEY' : 'test_key' })
60+ def test_create_llm_client (self ):
61+ """Test LLM client creation"""
62+ client = create_llm_client ()
63+ self .assertIsNotNone (client )
64+
65+ @patch ('tools.plan_exec_llm.OpenAI' )
66+ def test_query_llm (self , mock_openai ):
67+ """Test LLM querying"""
68+ # Mock the OpenAI response
69+ mock_response = MagicMock ()
70+ mock_response .choices = [MagicMock (message = MagicMock (content = "Test response" ))]
71+ mock_client = MagicMock ()
72+ mock_client .chat .completions .create .return_value = mock_response
73+ mock_openai .return_value = mock_client
74+
75+ # Test with various combinations of parameters
76+ response = query_llm ("Test plan" , "Test prompt" , "Test file content" )
77+ self .assertEqual (response , "Test response" )
78+
79+ response = query_llm ("Test plan" , "Test prompt" )
80+ self .assertEqual (response , "Test response" )
81+
82+ response = query_llm ("Test plan" )
83+ self .assertEqual (response , "Test response" )
84+
85+ # Verify the OpenAI client was called with correct parameters
86+ mock_client .chat .completions .create .assert_called_with (
87+ model = "o1" ,
88+ messages = [
89+ {"role" : "system" , "content" : unittest .mock .ANY },
90+ {"role" : "user" , "content" : unittest .mock .ANY }
91+ ],
92+ response_format = {"type" : "text" },
93+ reasoning_effort = "low"
94+ )
95+
96+ if __name__ == '__main__' :
97+ unittest .main ()
0 commit comments