import unittest from datetime import datetime import xml.etree.ElementTree as ET from sia.command import Command from sia.delete_command import DeleteCommand from sia.stop_command import StopCommand from sia.entry import Entry from sia.background_entry import BackgroundEntry from sia.entry.parse_error_entry import ParseErrorEntry from sia.read_entry import ReadEntry from sia.reasoning_entry import ReasoningEntry from sia.repeat_entry import RepeatEntry from sia.single_entry import SingleEntry from sia.entry.write_entry import WriteEntry from sia.web_io_buffer import WebIOBuffer from sia.response_parser import ResponseParser class ResponseParserTest(unittest.TestCase): def setUp(self): """Set up test cases with parser and IO buffer""" self.io_buffer = WebIOBuffer() self.parser = ResponseParser(self.io_buffer) def test_delete_command(self): """Test parsing delete command""" xml = '' result = self.parser.parse(xml) self.assertIsInstance(result, DeleteCommand) self.assertEqual(result.id, "test-id-123") def test_delete_command_missing_id(self): """Test parsing delete command without ID returns error entry""" xml = '' result = self.parser.parse(xml) self.assertIsInstance(result, ParseErrorEntry) self.assertEqual(result.content, xml) self.assertIn("missing required 'id'", result.error) def test_stop_command(self): """Test parsing stop command""" xml = '' result = self.parser.parse(xml) self.assertIsInstance(result, StopCommand) def test_background_entry(self): """Test parsing background entry""" xml = 'echo test' result = self.parser.parse(xml) self.assertIsInstance(result, BackgroundEntry) self.assertEqual(result.script, "echo test") def test_background_entry_empty_script(self): """Test parsing background entry with empty script returns error entry""" xml = '' result = self.parser.parse(xml) self.assertIsInstance(result, ParseErrorEntry) self.assertEqual(result.content, xml) self.assertIn("Background entry requires (only) script content", result.error) def test_repeat_entry(self): """Test parsing repeat entry""" xml = 'ls -l' result = self.parser.parse(xml) self.assertIsInstance(result, RepeatEntry) self.assertEqual(result.script, "ls -l") def test_repeat_entry_empty_script(self): """Test parsing repeat entry with empty script returns error entry""" xml = '' result = self.parser.parse(xml) self.assertIsInstance(result, ParseErrorEntry) self.assertEqual(result.content, xml) self.assertIn("Repeat entry requires (only) script content", result.error) def test_single_entry(self): """Test parsing single shot entry""" xml = 'echo "one time"' result = self.parser.parse(xml) self.assertIsInstance(result, SingleEntry) self.assertEqual(result.script, 'echo "one time"') def test_single_entry_empty_script(self): """Test parsing single shot entry with empty script returns error entry""" xml = '' result = self.parser.parse(xml) self.assertIsInstance(result, ParseErrorEntry) self.assertEqual(result.content, xml) self.assertIn("Single entry requires (only) script content", result.error) def test_reasoning_entry(self): """Test parsing reasoning entry""" xml = 'test reasoning' result = self.parser.parse(xml) self.assertIsInstance(result, ReasoningEntry) self.assertEqual(result.content, "test reasoning") def test_reasoning_entry_empty_content(self): """Test parsing reasoning entry with empty content returns error entry""" xml = '' result = self.parser.parse(xml) self.assertIsInstance(result, ParseErrorEntry) self.assertEqual(result.content, xml) self.assertIn("Reasoning entry requires (only) text content", result.error) def test_read_stdin_entry(self): """Test parsing read stdin entry""" xml = '' result = self.parser.parse(xml) self.assertIsInstance(result, ReadEntry) def test_write_stdout_entry(self): """Test parsing write stdout entry""" xml = 'test output' result = self.parser.parse(xml) self.assertIsInstance(result, WriteEntry) self.assertEqual(result.content, "test output") self.assertEqual(result.io_buffer, self.io_buffer) def test_write_stdout_entry_empty_content(self): """Test parsing write stdout entry with empty content returns error entry""" xml = '' result = self.parser.parse(xml) self.assertIsInstance(result, ParseErrorEntry) self.assertEqual(result.content, xml) self.assertIn("Write stdout entry requires (only) text content", result.error) def test_unknown_element(self): """Test parsing unknown element returns error entry""" xml = 'test' result = self.parser.parse(xml) self.assertIsInstance(result, ParseErrorEntry) self.assertEqual(result.content, xml) self.assertIn("Unknown root element", result.error) def test_malformed_xml(self): """Test parsing malformed XML returns error entry""" xml = '' result = self.parser.parse(xml) self.assertIsInstance(result, ParseErrorEntry) self.assertEqual(result.content, xml) self.assertIn("Invalid XML", result.error) def test_entry_id_generation(self): """Test that unique IDs are generated for entries""" xml1 = 'test 1' xml2 = 'test 2' result1 = self.parser.parse(xml1) result2 = self.parser.parse(xml2) self.assertNotEqual(result1.id, result2.id) def test_whitespace_handling(self): """Test handling of whitespace in XML""" xml = """ test content with multiple lines """ result = self.parser.parse(xml) self.assertIsInstance(result, ReasoningEntry) self.assertTrue(result.content.strip()) def test_cdata_content(self): """Test parsing content with CDATA sections""" xml = """ & chars]]> """ result = self.parser.parse(xml) self.assertIsInstance(result, ReasoningEntry) self.assertEqual(result.content, "Test content with & chars") def test_empty_element_with_attributes(self): """Test parsing empty element with attributes""" xml = '' result = self.parser.parse(xml) self.assertIsInstance(result, ReadEntry) def test_error_in_content_extraction(self): """Test handling errors during content extraction""" xml = '' # Malformed CDATA result = self.parser.parse(xml) self.assertIsInstance(result, ParseErrorEntry) self.assertEqual(result.content, xml) self.assertIn("Invalid XML", result.error)