import pytest from pathlib import Path from openpyxl import Workbook from src.core.mil_data_excel import read_excel_data, get_data_log, ExcelReaderConfig from src.core.exceptions import ExcelReadError, ExcelFormatError def test_read_excel_data_returns_required_keys(sample_excel_path: Path): """验证返回结果包含必需键""" result = read_excel_data(sample_excel_path) assert "wb" in result assert "sheet" in result assert "source_row" in result def test_read_excel_data_contains_signals(sample_excel_path: Path): """验证能解析出信号数据""" result = read_excel_data(sample_excel_path) signal_keys = [k for k in result.keys() if k not in ("wb", "sheet", "source_row")] assert len(signal_keys) > 0, "应至少包含一个信号" for name in signal_keys: assert "type" in result[name] assert "column" in result[name] assert "datalog" in result[name] def test_read_excel_file_not_found(): """文件不存在时抛出 ExcelReadError""" with pytest.raises(ExcelReadError, match="不存在"): read_excel_data("nonexistent.xlsx") def test_read_excel_missing_sheet(tmp_path: Path): """缺少 Scenario1 表时抛出 ExcelFormatError""" wb = Workbook() wb.create_sheet("WrongSheet") invalid_path = tmp_path / "invalid.xlsx" wb.save(invalid_path) with pytest.raises(ExcelFormatError, match="缺少"): read_excel_data(invalid_path) def test_read_excel_missing_source_header(tmp_path: Path): """缺少 Source: Input 标记时抛出 ExcelFormatError""" wb = Workbook() sheet = wb.active sheet.title = ExcelReaderConfig().sheet_name sheet.cell(1, 1, "time") sheet.cell(1, 2, "signal1") invalid_path = tmp_path / "missing_header.xlsx" wb.save(invalid_path) with pytest.raises(ExcelFormatError, match="缺少"): read_excel_data(invalid_path) def test_datalog_is_list(sample_excel_path: Path): """验证 datalog 是 DataLog 对象列表""" result = read_excel_data(sample_excel_path) signal_keys = [k for k in result.keys() if k not in ("wb", "sheet", "source_row")] assert len(signal_keys) > 0 first_signal = result[signal_keys[0]] assert len(first_signal["datalog"]) > 0 assert hasattr(first_signal["datalog"][0], "time") assert hasattr(first_signal["datalog"][0], "value") def test_get_data_log_empty_sheet(): """空 sheet 返回空列表""" wb = Workbook() sheet = wb.active datalog = get_data_log(sheet, row=1, column=1) assert len(datalog) == 0 def test_read_excel_data_return_object(sample_excel_path: Path): """验证 return_object=True 时返回 ExcelDataResult 对象""" from src.core.base import ExcelDataResult, SignalData result = read_excel_data(sample_excel_path, return_object=True) assert isinstance(result, ExcelDataResult) assert result.sheet_name == "Scenario1" assert result.source_row > 0 assert len(result.signals) > 0 def test_read_excel_data_signal_data_access(sample_excel_path: Path): """验证 ExcelDataResult 的信号访问方法""" from src.core.base import SignalData result = read_excel_data(sample_excel_path, return_object=True) signal_names = result.get_signal_names() assert len(signal_names) > 0 first_signal_name = signal_names[0] signal = result.get_signal(first_signal_name) assert isinstance(signal, SignalData) assert signal.datalog is not None def test_excel_reader_config_defaults(): """验证 ExcelReaderConfig 默认值""" config = ExcelReaderConfig() assert config.sheet_name == "Scenario1" assert config.source_header == "Source: Input" assert config.time_column == 1 assert config.header_row == 1 assert config.type_row == 3 assert config.data_start_row_offset == 1 def test_excel_reader_config_custom(): """验证 ExcelReaderConfig 自定义值""" config = ExcelReaderConfig( sheet_name="CustomSheet", source_header="CustomHeader", time_column=2, header_row=2, type_row=4, data_start_row_offset=2 ) assert config.sheet_name == "CustomSheet" assert config.source_header == "CustomHeader" assert config.time_column == 2 assert config.header_row == 2 assert config.type_row == 4 assert config.data_start_row_offset == 2 def test_read_excel_with_custom_config(tmp_path: Path): """验证使用自定义配置读取 Excel""" wb = Workbook() sheet = wb.active sheet.title = "CustomSheet" sheet.cell(1, 1, "time") sheet.cell(1, 2, "signal1") sheet.cell(2, 1, "CustomHeader") sheet.cell(2, 2, "CustomHeader") sheet.cell(3, 1, "Type1") sheet.cell(4, 1, 0.0) sheet.cell(4, 2, "value1") sheet.cell(5, 1, 1.0) sheet.cell(5, 2, "value2") custom_path = tmp_path / "custom.xlsx" wb.save(custom_path) config = ExcelReaderConfig( sheet_name="CustomSheet", source_header="CustomHeader" ) result = read_excel_data(custom_path, return_object=True, config=config) assert result.sheet_name == "CustomSheet" assert "signal1" in result.signals