import unittest
from unittest.mock import MagicMock, patch, mock_open
import tempfile
import os
import json
import csv
import sys
from pathlib import Path
import pytest
from semantica.parse.document_parser import DocumentParser, PDFParser, DOCXParser, HTMLParser
from semantica.parse.pptx_parser import PPTXParser
from semantica.parse.excel_parser import ExcelParser
from semantica.parse.structured_data_parser import StructuredDataParser, JSONParser, CSVParser, XMLParser
from semantica.parse.email_parser import EmailParser
from semantica.parse.code_parser import CodeParser
from semantica.parse.media_parser import MediaParser, ImageParser
from semantica.parse.web_parser import WebParser
from semantica.parse.registry import MethodRegistry
from semantica.parse.config import ParseConfig
pytestmark = pytest.mark.integration
class TestParseComprehensive(unittest.TestCase):
def setUp(self):
# Common mocks
self.mock_logger = MagicMock()
self.mock_tracker = MagicMock()
# Patch loggers and trackers
self.patchers = []
modules_to_patch = [
'semantica.parse.document_parser',
'semantica.parse.structured_data_parser',
'semantica.parse.email_parser',
'semantica.parse.code_parser',
'semantica.parse.media_parser',
'semantica.parse.web_parser',
'semantica.parse.pdf_parser',
'semantica.parse.docx_parser',
'semantica.parse.pptx_parser',
'semantica.parse.excel_parser',
'semantica.parse.html_parser',
'semantica.parse.json_parser',
'semantica.parse.csv_parser',
'semantica.parse.xml_parser',
'semantica.parse.image_parser'
]
for module_name in modules_to_patch:
# Patch get_logger
try:
p1 = patch(f'{module_name}.get_logger', return_value=self.mock_logger)
p1.start()
self.patchers.append(p1)
except AttributeError:
pass
# Patch get_progress_tracker
# Check if module has get_progress_tracker before patching to avoid AttributeError
try:
# We need to import the module to check attributes
mod = __import__(module_name, fromlist=['get_progress_tracker'])
if hasattr(mod, 'get_progress_tracker'):
p2 = patch(f'{module_name}.get_progress_tracker', return_value=self.mock_tracker)
p2.start()
self.patchers.append(p2)
except ImportError:
pass
def tearDown(self):
for p in self.patchers:
p.stop()
# --- Structured Data Parser Tests ---
def test_json_parser(self):
parser = JSONParser()
data = {'key': 'value', 'list': [1, 2, 3]}
with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.json') as tmp:
json.dump(data, tmp)
tmp_path = tmp.name
try:
result = parser.parse(tmp_path)
self.assertEqual(result.data['key'], 'value')
self.assertEqual(result.data['list'], [1, 2, 3])
# Metadata depends on implementation, source/type are likely keys
self.assertIn('source', result.metadata)
self.assertIn('type', result.metadata)
finally:
os.remove(tmp_path)
def test_csv_parser(self):
parser = CSVParser()
rows = [['name', 'age'], ['Alice', '30'], ['Bob', '25']]
with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.csv', newline='') as tmp:
writer = csv.writer(tmp)
writer.writerows(rows)
tmp_path = tmp.name
try:
result = parser.parse(tmp_path)
# CSVData has rows attribute
self.assertEqual(len(result.rows), 2) # Header is not data
self.assertEqual(result.rows[0]['name'], 'Alice')
self.assertEqual(result.rows[1]['age'], '25')
finally:
os.remove(tmp_path)
def test_xml_parser(self):
parser = XMLParser()
xml_content = """
Hello World
""" with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.html') as tmp: tmp.write(html_content) tmp_path = tmp.name try: result = parser.parse(tmp_path) # Returns HTMLData (dataclass) - I modified it to return HTMLData with metadata as dict self.assertEqual(result.metadata.get('title'), 'Test HTML') self.assertIn('Hello World', result.text) finally: os.remove(tmp_path) # --- Document Parser Tests (General) --- def test_document_parser_txt(self): parser = DocumentParser() content = "Simple text file." with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.txt') as tmp: tmp.write(content) tmp_path = tmp.name try: text = parser.extract_text(tmp_path) self.assertEqual(text, content) finally: os.remove(tmp_path) # --- Structured Data Parser Tests (Delegation) --- def test_structured_data_parser_json_delegation(self): parser = StructuredDataParser() data = {'key': 'value'} with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.json') as tmp: json.dump(data, tmp) tmp_path = tmp.name try: result = parser.parse_data(tmp_path, data_format='json') # Returns dict (JSONData.__dict__) # JSONData has .data field self.assertEqual(result['data']['key'], 'value') finally: os.remove(tmp_path) if __name__ == '__main__': unittest.main()