import unittest from unittest.mock import MagicMock, patch from pathlib import Path import json import tempfile import os from semantica.parse.structured_data_parser import StructuredDataParser from semantica.parse.json_parser import JSONParser, JSONData class TestParser(unittest.TestCase): def setUp(self): self.mock_logger = MagicMock() self.mock_tracker = MagicMock() self.logger_patcher = patch('semantica.parse.structured_data_parser.get_logger', return_value=self.mock_logger) self.tracker_patcher = patch('semantica.parse.structured_data_parser.get_progress_tracker', return_value=self.mock_tracker) self.logger_patcher_jp = patch('semantica.parse.json_parser.get_logger', return_value=self.mock_logger) self.tracker_patcher_jp = patch('semantica.parse.json_parser.get_progress_tracker', return_value=self.mock_tracker) self.logger_patcher.start() self.tracker_patcher.start() self.logger_patcher_jp.start() self.tracker_patcher_jp.start() # Also patch CSVParser and XMLParser imports in structured_data_parser if they cause issues, # but they should be fine if files exist. # Assuming they are importable. def tearDown(self): self.logger_patcher.stop() self.tracker_patcher.stop() self.logger_patcher_jp.stop() self.tracker_patcher_jp.stop() def test_json_parser_string(self): parser = JSONParser() json_content = '{"key": "value"}' # If the parser supports string content (check logic in read file) # The code read previously showed checks for file existence. # If it's not a file, it might try to parse as string or fail if logic assumes path. # Let's check the code snippet again or try. # The snippet says: "if file_path_obj: ... else: ... (not shown fully)" # Let's assume it supports string or we can use a temp file. # Using temp file is safer with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.json') as tmp: tmp.write(json_content) tmp_path = tmp.name try: result = parser.parse(tmp_path) self.assertIsInstance(result, JSONData) self.assertEqual(result.data['key'], 'value') finally: os.remove(tmp_path) def test_structured_data_parser_init(self): parser = StructuredDataParser() self.assertIsInstance(parser.json_parser, JSONParser) # Check other parsers exist self.assertTrue(hasattr(parser, 'csv_parser')) self.assertTrue(hasattr(parser, 'xml_parser')) @patch('semantica.parse.structured_data_parser.JSONParser') def test_structured_data_parser_delegation(self, mock_json_parser_cls): mock_instance = mock_json_parser_cls.return_value parser = StructuredDataParser() parser.progress_tracker = MagicMock() # Mock progress tracker manually if not set by init due to patch issues or if init needs it # Mock _detect_format or provide format # If we provide format='json', it should use json_parser parser.json_parser = mock_instance # replace with mock instance # We need to ensure Path is not mocked in a way that breaks isinstance check # Instead of patching Path globally, we can just rely on the fact that "test.json" string # will trigger Path(data).exists() check. # We can mock Path inside the module but that breaks isinstance. # Better approach: Let it use real Path but mock exists on the path object if possible, # OR just use a real file or a string that doesn't exist but bypass the check if possible? # The code checks: isinstance(data, Path) or (isinstance(data, str) and Path(data).exists()) # If we pass a string "test.json" and it doesn't exist, file_path will be None. # But we want it to proceed. # If file_path is None, it uses 'content' message but still calls _detect_format or uses provided format. # Let's just avoid patching Path globally to fix isinstance error. # We can patch os.path.exists or Path.exists if we want to simulate file existence # OR just pass a string and let it be treated as content if file missing. with patch.object(Path, 'exists', return_value=True): parser.parse_data("test.json", data_format="json") mock_instance.parse.assert_called() if __name__ == '__main__': unittest.main()