litellm-mirror/tests/litellm/llms/asi/chat/test_json_extraction.py
2025-04-14 22:43:05 -07:00

208 lines
7.8 KiB
Python

"""
Test the ASI JSON extraction module
"""
import unittest
import json
from unittest.mock import MagicMock, patch
from litellm.llms.asi.chat.json_extraction import extract_json
class TestASIJsonExtraction(unittest.TestCase):
"""Test the ASI JSON extraction functionality"""
def test_extract_json_from_markdown_code_block(self):
"""Test extracting JSON from markdown code blocks"""
# Test with JSON code block
content = """Here's the JSON data you requested:
```json
{
"name": "John Doe",
"age": 30,
"email": "john@example.com"
}
```
Let me know if you need anything else!"""
result = extract_json(content)
self.assertIsNotNone(result)
# Parse the result to check content regardless of formatting
if result is not None: # Add null check to prevent type errors
parsed = json.loads(result)
self.assertEqual(parsed["name"], "John Doe")
self.assertEqual(parsed["age"], 30)
self.assertEqual(parsed["email"], "john@example.com")
# Test with code block without language specifier
content = """Here's the data:
```
{
"name": "John Doe",
"age": 30,
"email": "john@example.com"
}
```
Let me know if you need anything else!"""
result = extract_json(content)
self.assertIsNotNone(result)
# Parse the result to check content regardless of formatting
if result is not None: # Add null check to prevent type errors
parsed = json.loads(result)
self.assertEqual(parsed["name"], "John Doe")
self.assertEqual(parsed["age"], 30)
self.assertEqual(parsed["email"], "john@example.com")
def test_extract_json_from_direct_json(self):
"""Test extracting JSON directly from content"""
# Test with direct JSON object
content = '{"name": "John Doe", "age": 30, "email": "john@example.com"}'
result = extract_json(content)
self.assertIsNotNone(result)
# Parse the result to check content regardless of formatting
if result is not None: # Add null check to prevent type errors
parsed = json.loads(result)
self.assertEqual(parsed["name"], "John Doe")
self.assertEqual(parsed["age"], 30)
self.assertEqual(parsed["email"], "john@example.com")
# Test with JSON object with whitespace
content = """
{
"name": "John Doe",
"age": 30,
"email": "john@example.com"
}
"""
result = extract_json(content)
self.assertIsNotNone(result)
if result is not None: # Add null check to prevent lint errors
parsed = json.loads(result)
self.assertEqual(parsed["name"], "John Doe")
self.assertEqual(parsed["age"], 30)
self.assertEqual(parsed["email"], "john@example.com")
# Test with JSON array
content = '[{"name": "John"}, {"name": "Jane"}]'
result = extract_json(content)
self.assertIsNotNone(result)
# Our implementation might only extract the first JSON object from an array
# or it might extract the entire array - we just check that it contains valid JSON
if result is not None: # Add null check to prevent lint errors
parsed = json.loads(result)
self.assertTrue(isinstance(parsed, (dict, list)))
# If it's a dict, it should contain "name"
if isinstance(parsed, dict) and "name" in parsed:
self.assertIn(parsed["name"], ["John", "Jane"])
# If it's a list, the first item should have "name"
elif isinstance(parsed, list) and len(parsed) > 0 and "name" in parsed[0]:
self.assertIn(parsed[0]["name"], ["John", "Jane"])
def test_extract_json_from_lists(self):
"""Test extracting JSON from lists"""
# Test with numbered list
content = """Here are the items:
1. Item 1 - Description 1
2. Item 2 - Description 2
3. Item 3 - Description 3
"""
result = extract_json(content)
self.assertIsNotNone(result)
if result is not None: # Add null check to prevent lint errors
parsed = json.loads(result)
self.assertTrue("items" in parsed)
self.assertTrue(isinstance(parsed["items"], list))
self.assertEqual(len(parsed["items"]), 3)
# Test with bulleted list
content = """Here are the items:
- Item 1: Description 1
- Item 2: Description 2
- Item 3: Description 3
"""
result = extract_json(content)
self.assertIsNotNone(result)
if result is not None: # Add null check to prevent lint errors
parsed = json.loads(result)
self.assertTrue("items" in parsed)
self.assertTrue(isinstance(parsed["items"], list))
self.assertEqual(len(parsed["items"]), 3)
def test_extract_json_unstructured_text(self):
"""Test extracting JSON from unstructured text"""
# Test with plain text
content = "This is just plain text without any JSON."
result = extract_json(content)
self.assertIsNotNone(result)
if result is not None: # Add null check to prevent lint errors
parsed = json.loads(result)
self.assertTrue("text" in parsed)
self.assertEqual(parsed["text"], content)
# Test with malformed JSON
content = '{"name": "John", "age": 30, "email": "john@example.com' # Missing closing brace
result = extract_json(content)
self.assertIsNotNone(result)
# Our implementation should handle malformed JSON gracefully
# It might return a text object or attempt to fix the JSON
if result is not None: # Add null check to prevent lint errors
parsed = json.loads(result)
self.assertTrue(isinstance(parsed, dict))
def test_extract_json_nested_structures(self):
"""Test extracting JSON with nested structures"""
# Test with nested objects
content = """
{
"person": {
"name": "John Doe",
"contact": {
"email": "john@example.com",
"phone": "123-456-7890"
}
},
"orders": [
{"id": 1, "product": "Laptop"},
{"id": 2, "product": "Phone"}
]
}
"""
result = extract_json(content)
self.assertIsNotNone(result)
if result is not None: # Add null check to prevent lint errors
parsed = json.loads(result)
# Our implementation might extract the full structure or just parts of it
# We check for key elements that should be present regardless
if "person" in parsed:
self.assertEqual(parsed["person"]["name"], "John Doe")
elif "name" in parsed:
self.assertEqual(parsed["name"], "John Doe")
elif "product" in parsed:
self.assertIn(parsed["product"], ["Laptop", "Phone"])
def test_extract_json_with_special_characters(self):
"""Test extracting JSON with special characters"""
# Test with JSON containing special characters
content = """
{
"description": "This is a \"quoted\" string with special chars: \\n\\t",
"url": "https://example.com/path?query=value&another=value"
}
"""
result = extract_json(content)
self.assertIsNotNone(result)
if result is not None: # Add null check to prevent lint errors
parsed = json.loads(result)
if "description" in parsed:
self.assertIn("quoted", parsed["description"])
if "url" in parsed:
self.assertIn("example.com", parsed["url"])
if __name__ == "__main__":
unittest.main()