# -*- coding: utf-8 -*- """Tests for layout_engine.py and form_parser.py""" import unittest import sys sys.stdout.reconfigure(encoding='utf-8') class TestFormParser(unittest.TestCase): """Test FormParser with mock layout analysis results.""" def setUp(self): from src.parser.form_parser import FormParser self.parser = FormParser() def _make_table(self, html, bbox=(0, 0, 800, 600)): """Helper to create a table result dict.""" return {'bbox': bbox, 'html': html, 'cells': []} def test_extract_vehicle_no_from_table(self): html = '
자동차등록번호서울 12가 3456
' layout = {'tables': [self._make_table(html)], 'text_regions': []} fields = self.parser.parse_layout(layout) self.assertIn('vehicle_no', fields) self.assertIn('서울 12가 3456', fields['vehicle_no']['value']) def test_extract_vin_from_table(self): html = '
차대번호KMHD341DBNU123456
' layout = {'tables': [self._make_table(html)], 'text_regions': []} fields = self.parser.parse_layout(layout) self.assertIn('vin', fields) self.assertEqual(fields['vin']['value'], 'KMHD341DBNU123456') def test_extract_dimensions_from_table(self): html = ( '' '' '' '
길이4,880너비1,860
높이1,475총중량1,990
' ) layout = {'tables': [self._make_table(html)], 'text_regions': []} fields = self.parser.parse_layout(layout) self.assertEqual(fields['length_mm']['value'], '4880') self.assertEqual(fields['width_mm']['value'], '1860') self.assertEqual(fields['height_mm']['value'], '1475') self.assertEqual(fields['total_weight_kg']['value'], '1990') def test_extract_owner_name_from_table(self): html = '
성명(명칭)홍길동
' layout = {'tables': [self._make_table(html)], 'text_regions': []} fields = self.parser.parse_layout(layout) self.assertIn('owner_name', fields) self.assertEqual(fields['owner_name']['value'], '홍길동') def test_extract_from_text_regions(self): regions = [ {'bbox': (100, 100, 200, 130), 'text': '차명', 'confidence': 0.95, 'region_type': 'text'}, {'bbox': (220, 100, 400, 130), 'text': '쏘나타', 'confidence': 0.92, 'region_type': 'text'}, ] layout = {'tables': [], 'text_regions': regions} fields = self.parser.parse_layout(layout, img_height=800, img_width=600) self.assertIn('model_name', fields) self.assertEqual(fields['model_name']['value'], '쏘나타') def test_circled_number_labels_matched(self): html = '
②차종승용차
' layout = {'tables': [self._make_table(html)], 'text_regions': []} fields = self.parser.parse_layout(layout) self.assertIn('vehicle_type', fields) self.assertEqual(fields['vehicle_type']['value'], '승용차') def test_empty_layout_returns_empty(self): layout = {'tables': [], 'text_regions': []} fields = self.parser.parse_layout(layout) self.assertEqual(fields, {}) def test_registration_date_cleaned(self): html = '
최초등록일2020년 01월 15일
' layout = {'tables': [self._make_table(html)], 'text_regions': []} fields = self.parser.parse_layout(layout) self.assertIn('registration_date', fields) self.assertIn('2020', fields['registration_date']['value']) def test_model_year_extracted(self): html = '
연식2023
' layout = {'tables': [self._make_table(html)], 'text_regions': []} fields = self.parser.parse_layout(layout) self.assertEqual(fields['model_year']['value'], '2023') def test_passenger_capacity_digits_only(self): html = '
승차정원5명
' layout = {'tables': [self._make_table(html)], 'text_regions': []} fields = self.parser.parse_layout(layout) self.assertEqual(fields['passenger_capacity']['value'], '5') def test_label_not_used_as_value(self): """Label cell followed by another label should not produce a field.""" html = '
차종차명
' layout = {'tables': [self._make_table(html)], 'text_regions': []} fields = self.parser.parse_layout(layout) # 차명 is also a label, so 차종 should not get 차명 as its value if 'vehicle_type' in fields: self.assertNotEqual(fields['vehicle_type']['value'], '차명') class TestLayoutEngine(unittest.TestCase): """Test LayoutEngine initialization and graceful degradation.""" def test_parse_table_html(self): from src.ocr.layout_engine import LayoutEngine cells = LayoutEngine._parse_table_html( '
AB
CD
' ) self.assertEqual(len(cells), 4) self.assertEqual(cells[0], {'row': 0, 'col': 0, 'text': 'A'}) self.assertEqual(cells[3], {'row': 1, 'col': 1, 'text': 'D'}) def test_parse_empty_html(self): from src.ocr.layout_engine import LayoutEngine cells = LayoutEngine._parse_table_html('') self.assertEqual(cells, []) def test_parse_nested_tags_stripped(self): from src.ocr.layout_engine import LayoutEngine cells = LayoutEngine._parse_table_html( '
Bold text
' ) self.assertEqual(cells[0]['text'], 'Bold text') if __name__ == '__main__': unittest.main()