Skip to main content
Glama

MCP Sheet Parser

by yuqie6
MIT License
3
  • Apple
test_xlsb_parser.py9.8 kB
import pytest from unittest.mock import MagicMock, patch, mock_open, PropertyMock from src.parsers.xlsb_parser import XlsbParser from src.models.table_model import Sheet, Style @pytest.fixture def mock_xlsb_workbook(): """Fixture for a mocked pyxlsb workbook.""" workbook = MagicMock() workbook.sheets = ["Sheet1"] worksheet = MagicMock() row = MagicMock() cell = MagicMock() cell.c = 0 cell.v = "Test" row.cells = [cell] worksheet.rows.return_value = [[cell]] workbook.get_sheet.return_value.__enter__.return_value = worksheet return workbook @patch('src.parsers.xlsb_parser.open_workbook') def test_parse_success(mock_open_workbook, mock_xlsb_workbook): """Test successful parsing of an XLSB file.""" mock_open_workbook.return_value.__enter__.return_value = mock_xlsb_workbook parser = XlsbParser() sheets = parser.parse("dummy.xlsb") assert len(sheets) == 1 assert isinstance(sheets[0], Sheet) assert sheets[0].name == "Sheet1" assert len(sheets[0].rows) == 1 assert len(sheets[0].rows[0].cells) == 1 assert sheets[0].rows[0].cells[0].value == "Test" @patch('src.parsers.xlsb_parser.open_workbook') def test_parse_no_sheets(mock_open_workbook, mock_xlsb_workbook): """Test parsing a workbook with no sheets.""" mock_xlsb_workbook.sheets = [] mock_open_workbook.return_value.__enter__.return_value = mock_xlsb_workbook parser = XlsbParser() with pytest.raises(RuntimeError, match="工作簿不包含任何工作表"): parser.parse("dummy.xlsb") def test_process_cell_value(): """Test _process_cell_value with different value types.""" parser = XlsbParser() assert parser._process_cell_value(None) is None assert parser._process_cell_value("Hello") == "Hello" assert parser._process_cell_value(123) == 123 assert parser._process_cell_value(123.45) == 123.45 assert parser._process_cell_value(True) is True def test_extract_basic_style(): """Test _extract_basic_style.""" parser = XlsbParser() cell_data = MagicMock() cell_data.s = 1 cell_data.f = "0.00" cell_data.v = 12.34 style = parser._extract_basic_style(cell_data) assert isinstance(style, Style) assert style.number_format == "0.00" def test_get_sheet_names(mock_xlsb_workbook): """Test _get_sheet_names.""" parser = XlsbParser() names = parser._get_sheet_names(mock_xlsb_workbook) assert names == ["Sheet1"] def test_normalize_row_data(): """Test _normalize_row_data.""" parser = XlsbParser() cell1 = MagicMock(); cell1.c = 0; cell1.v = 'A' cell2 = MagicMock(); cell2.c = 2; cell2.v = 'C' row_data = [cell1, cell2] normalized = parser._normalize_row_data(row_data, 3) assert normalized == ['A', None, 'C'] def test_streaming_support(): """Test streaming support methods.""" parser = XlsbParser() assert parser.supports_streaming() is False assert parser.create_lazy_sheet("dummy.xlsb") is None class TestProcessCellValueEdgeCases: """测试_process_cell_value的边界情况。""" def test_process_cell_value_date_conversion_exception(self): """ TDD测试:_process_cell_value应该处理日期转换异常 这个测试覆盖第129-132行的异常处理代码 """ parser = XlsbParser() # 模拟一个会导致日期转换异常的数值 with patch('src.parsers.xlsb_parser.datetime') as mock_datetime: mock_datetime.fromordinal.side_effect = ValueError("Invalid date") # 测试一个在日期范围内但转换失败的数值 result = parser._process_cell_value(40000.0) # 在日期范围内 # 应该返回原始数值而不是日期 assert result == 40000.0 def test_process_cell_value_integer_conversion(self): """ TDD测试:_process_cell_value应该正确处理整数转换 这个测试覆盖第135-136行的整数转换代码 """ parser = XlsbParser() # 测试浮点数转整数 result = parser._process_cell_value(123.0) assert result == 123 assert isinstance(result, int) # 测试非整数浮点数 result = parser._process_cell_value(123.45) assert result == 123.45 assert isinstance(result, float) def test_process_cell_value_boolean_handling(self): """ TDD测试:_process_cell_value应该正确处理布尔值 这个测试覆盖第138-139行的布尔值处理代码 """ parser = XlsbParser() # 测试布尔值 assert parser._process_cell_value(True) is True assert parser._process_cell_value(False) is False def test_process_cell_value_other_types_conversion(self): """ TDD测试:_process_cell_value应该将其他类型转换为字符串 这个测试覆盖第140-142行的其他类型转换代码 """ parser = XlsbParser() # 测试列表转字符串 result = parser._process_cell_value([1, 2, 3]) assert result == "[1, 2, 3]" # 测试字典转字符串 result = parser._process_cell_value({"key": "value"}) assert result == "{'key': 'value'}" class TestExtractBasicStyleEdgeCases: """测试_extract_basic_style的边界情况。""" def test_extract_basic_style_empty_cell_data(self): """ TDD测试:_extract_basic_style应该处理空单元格数据 这个测试覆盖第151行的空数据处理代码 """ parser = XlsbParser() # 测试None result = parser._extract_basic_style(None) assert result is None # 测试空字典 result = parser._extract_basic_style({}) assert result is None # 测试空列表 result = parser._extract_basic_style([]) assert result is None def test_extract_basic_style_date_number_format(self): """ TDD测试:_extract_basic_style应该为日期设置正确的数字格式 这个测试覆盖第182行的日期格式设置代码 """ parser = XlsbParser() # 创建模拟的单元格数据,包含日期范围内的数值 mock_cell_data = MagicMock() mock_cell_data.v = 44000.0 # 在日期范围内的数值 mock_cell_data.s = 1 # 样式索引,表示有自定义格式 result = parser._extract_basic_style(mock_cell_data) # 验证返回了Style对象且设置了日期格式 assert isinstance(result, Style) assert result.number_format == "yyyy-mm-dd" def test_extract_basic_style_integer_number_format(self): """ TDD测试:_extract_basic_style应该为整数设置正确的数字格式 这个测试覆盖第185-186行的整数格式设置代码 """ parser = XlsbParser() # 创建模拟的单元格数据,包含整数 mock_cell_data = MagicMock() mock_cell_data.v = 123 mock_cell_data.s = 1 # 样式索引,表示有自定义格式 result = parser._extract_basic_style(mock_cell_data) # 验证返回了Style对象且设置了整数格式 assert isinstance(result, Style) assert result.number_format == "0" class TestGetSheetNamesExceptionHandling: """测试get_sheet_names的异常处理。""" def test_get_sheet_names_exception_handling(self): """ TDD测试:_get_sheet_names应该处理异常情况 这个测试覆盖第210-212行的异常处理代码 """ parser = XlsbParser() # 创建一个会抛出异常的模拟工作簿 mock_workbook = MagicMock() # 直接让sheets属性访问时抛出异常 type(mock_workbook).sheets = PropertyMock(side_effect=RuntimeError("Access error")) with patch('src.parsers.xlsb_parser.logger') as mock_logger: result = parser._get_sheet_names(mock_workbook) # 验证返回空列表 assert result == [] # 验证记录了警告日志 mock_logger.warning.assert_called_once() warning_call = mock_logger.warning.call_args[0][0] assert "获取工作表名称失败" in warning_call class TestParseWithNullCellValues: """测试解析包含空值单元格的情况。""" @patch('src.parsers.xlsb_parser.open_workbook') def test_parse_with_null_cell_values(self, mock_open_workbook): """ TDD测试:parse应该正确处理包含空值的单元格 这个测试覆盖第71-72行的空值处理代码 """ # 创建包含空值单元格的模拟工作簿 workbook = MagicMock() workbook.sheets = ["Sheet1"] worksheet = MagicMock() # 创建一个空值单元格 null_cell = MagicMock() null_cell.c = 0 null_cell.v = None # 空值 # 创建一个正常单元格 normal_cell = MagicMock() normal_cell.c = 1 normal_cell.v = "Test" worksheet.rows.return_value = [[null_cell, normal_cell]] workbook.get_sheet.return_value.__enter__.return_value = worksheet mock_open_workbook.return_value.__enter__.return_value = workbook parser = XlsbParser() sheets = parser.parse("dummy.xlsb") # 验证解析结果 assert len(sheets) == 1 assert len(sheets[0].rows) == 1 assert len(sheets[0].rows[0].cells) == 2 # 验证空值单元格被正确处理 assert sheets[0].rows[0].cells[0].value is None assert sheets[0].rows[0].cells[0].style is None # 验证正常单元格 assert sheets[0].rows[0].cells[1].value == "Test"

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/yuqie6/MCP-Sheet-Parser-cot'

If you have feedback or need assistance with the MCP directory API, please join our Discord server