Files
Claude-Code-Workflow/codex-lens/tests/real/comparison_test.py
catlog22 2f3a14e946 Add unit tests for LspGraphBuilder class
- Implement comprehensive unit tests for the LspGraphBuilder class to validate its functionality in building code association graphs.
- Tests cover various scenarios including single level graph expansion, max nodes and depth boundaries, concurrent expansion limits, document symbol caching, error handling during node expansion, and edge cases such as empty seed lists and self-referencing nodes.
- Utilize pytest and asyncio for asynchronous testing and mocking of LspBridge methods.
2026-01-20 12:49:31 +08:00

163 lines
5.0 KiB
Python

#!/usr/bin/env python
"""Direct comparison: standalone manager vs direct subprocess."""
import asyncio
import json
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent.parent.parent / "src"))
async def test_direct():
"""Direct subprocess test that WORKS."""
print("\n=== DIRECT SUBPROCESS TEST ===")
process = await asyncio.create_subprocess_exec(
'pyright-langserver', '--stdio',
stdin=asyncio.subprocess.PIPE,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
cwd=str(Path(__file__).parent.parent.parent),
)
def encode(msg):
body = json.dumps(msg).encode('utf-8')
header = f'Content-Length: {len(body)}\r\n\r\n'.encode('ascii')
return header + body
async def read_message(timeout=5.0):
content_length = 0
while True:
try:
line = await asyncio.wait_for(process.stdout.readline(), timeout=timeout)
except asyncio.TimeoutError:
return None
if not line:
return None
line_str = line.decode('ascii').strip()
if not line_str:
break
if line_str.lower().startswith('content-length:'):
content_length = int(line_str.split(':')[1].strip())
if content_length == 0:
return None
body = await process.stdout.readexactly(content_length)
return json.loads(body.decode('utf-8'))
# Initialize
init = {
'jsonrpc': '2.0', 'id': 1, 'method': 'initialize',
'params': {
'processId': 12345,
'rootUri': 'file:///D:/Claude_dms3/codex-lens',
'rootPath': 'D:/Claude_dms3/codex-lens',
'capabilities': {
'textDocument': {
'synchronization': {'dynamicRegistration': False},
'documentSymbol': {'hierarchicalDocumentSymbolSupport': True},
},
'workspace': {'configuration': True, 'workspaceFolders': True},
},
'workspaceFolders': [{'uri': 'file:///D:/Claude_dms3/codex-lens', 'name': 'codex-lens'}],
'initializationOptions': {},
}
}
process.stdin.write(encode(init))
await process.stdin.drain()
while True:
msg = await read_message(5.0)
if msg is None or msg.get('id') == 1:
print(f" Got initialize response")
break
# Initialized
process.stdin.write(encode({'jsonrpc': '2.0', 'method': 'initialized', 'params': {}}))
await process.stdin.drain()
print(" Sent initialized")
# didOpen with simple content
did_open = {
'jsonrpc': '2.0', 'method': 'textDocument/didOpen',
'params': {
'textDocument': {
'uri': 'file:///D:/Claude_dms3/codex-lens/simple.py',
'languageId': 'python',
'version': 1,
'text': 'def hello():\n pass\n'
}
}
}
process.stdin.write(encode(did_open))
await process.stdin.drain()
print(" Sent didOpen")
# Read and respond to configuration requests
print(" Waiting for messages...")
for i in range(15):
msg = await read_message(2.0)
if msg is None:
continue
method = msg.get('method')
print(f" RECV: id={msg.get('id')}, method={method}")
if method == 'workspace/configuration':
process.stdin.write(encode({'jsonrpc': '2.0', 'id': msg['id'], 'result': [{}]}))
await process.stdin.drain()
if method == 'textDocument/publishDiagnostics':
break
# documentSymbol
doc_sym = {
'jsonrpc': '2.0', 'id': 2, 'method': 'textDocument/documentSymbol',
'params': {'textDocument': {'uri': 'file:///D:/Claude_dms3/codex-lens/simple.py'}}
}
process.stdin.write(encode(doc_sym))
await process.stdin.drain()
print(" Sent documentSymbol")
for i in range(5):
msg = await read_message(3.0)
if msg is None:
continue
if msg.get('id') == 2:
result = msg.get('result', [])
print(f" GOT {len(result)} SYMBOLS!")
break
process.terminate()
await process.wait()
async def test_manager():
"""Standalone manager test that FAILS."""
print("\n=== STANDALONE MANAGER TEST ===")
from codexlens.lsp.standalone_manager import StandaloneLspManager
workspace = Path(__file__).parent.parent.parent
manager = StandaloneLspManager(
workspace_root=str(workspace),
timeout=30.0
)
await manager.start()
simple_file = workspace / "simple.py"
simple_file.write_text('def hello():\n pass\n')
try:
symbols = await manager.get_document_symbols(str(simple_file))
print(f" GOT {len(symbols)} SYMBOLS!")
finally:
simple_file.unlink(missing_ok=True)
await manager.stop()
async def main():
await test_direct()
await test_manager()
if __name__ == "__main__":
asyncio.run(main())