""" 测试文档索引处理的变更 文件: src/knowledge/indexing.py """ import os import sys from pathlib import Path project_root = Path(__file__).parent.parent sys.path.insert(0, str(project_root)) import pytest import pandas as pd from openpyxl import Workbook from src.knowledge.indexing import process_file_to_markdown, _make_unique_columns class TestMakeUniqueColumns: """测试新增的 _make_unique_columns 函数""" def test_no_duplicates(self): """测试没有重复列名的情况""" columns = ["列A", "列B", "列C", "列D"] result = _make_unique_columns(columns) assert result == columns print(f"✓ 无重复列名处理正确: {result}") def test_with_duplicates(self): """测试有重复列名的情况""" columns = ["姓名", "年龄", "姓名", "地址", "年龄", "姓名"] result = _make_unique_columns(columns) expected = ["姓名", "年龄", "姓名_2", "地址", "年龄_2", "姓名_3"] assert result == expected print(f"✓ 重复列名处理正确: {result}") def test_with_none_values(self): """测试包含 None 值的列名""" columns = ["A", None, "B", None, "C"] result = _make_unique_columns(columns) assert result[0] == "A" assert result[1] == "Unnamed" assert result[2] == "B" assert result[3] == "Unnamed_2" assert result[4] == "C" print(f"✓ None 值处理正确: {result}") def test_with_empty_strings(self): """测试包含空字符串的列名""" columns = ["A", "", "B", " ", "C"] result = _make_unique_columns(columns) # 空字符串应该被转换为 "Unnamed" assert result[0] == "A" assert result[1] == "Unnamed" assert result[2] == "B" assert result[3] == "Unnamed_2" assert result[4] == "C" print(f"✓ 空字符串处理正确: {result}") def test_empty_list(self): """测试空列表""" columns = [] result = _make_unique_columns(columns) assert result == [] print(f"✓ 空列表处理正确") def test_all_same_names(self): """测试所有列名相同的情况""" columns = ["数据", "数据", "数据", "数据"] result = _make_unique_columns(columns) expected = ["数据", "数据_2", "数据_3", "数据_4"] assert result == expected print(f"✓ 全部相同列名处理正确: {result}") class TestExcelProcessingChanges: """测试 Excel 处理逻辑的变更""" @pytest.mark.asyncio async def test_excel_basic_processing(self, tmp_path): """测试基础 Excel 处理""" # 创建测试 Excel 文件 test_file = tmp_path / "test_basic.xlsx" wb = Workbook() ws = wb.active ws.title = "测试表" # 添加表头 ws["A1"] = "姓名" ws["B1"] = "年龄" ws["C1"] = "城市" # 添加数据 data = [ ["张三", 25, "北京"], ["李四", 30, "上海"], ["王五", 28, "广州"], ] for i, row in enumerate(data, start=2): for j, value in enumerate(row, start=1): ws.cell(row=i, column=j, value=value) wb.save(test_file) # 处理文件 result = await process_file_to_markdown(str(test_file)) # 验证结果 assert result is not None assert "测试表" in result assert "表格标题" in result # 新增的标题列 assert "姓名" in result assert "张三" in result print(f"✓ 基础 Excel 处理成功") print(f"处理结果预览:\n{result[:300]}...") @pytest.mark.asyncio async def test_excel_merged_cells(self, tmp_path): """测试包含合并单元格的 Excel 处理""" test_file = tmp_path / "test_merged.xlsx" wb = Workbook() ws = wb.active ws.title = "合并单元格测试" # 添加表头 ws["A1"] = "部门" ws["B1"] = "员工" ws["C1"] = "工资" # 添加数据并合并单元格 ws["A2"] = "技术部" ws.merge_cells("A2:A4") # 合并 A2:A4 ws["B2"] = "员工1" ws["B3"] = "员工2" ws["B4"] = "员工3" ws["C2"] = 10000 ws["C3"] = 12000 ws["C4"] = 11000 wb.save(test_file) # 处理文件 result = await process_file_to_markdown(str(test_file)) # 验证结果 - 合并单元格的值应该填充到所有单元格 assert result is not None assert "合并单元格测试" in result assert "技术部" in result assert "员工1" in result print(f"✓ 合并单元格 Excel 处理成功") print(f"处理结果预览:\n{result[:400]}...") @pytest.mark.asyncio async def test_excel_chunking(self, tmp_path): """测试 Excel 每 10 行分块处理""" test_file = tmp_path / "test_chunking.xlsx" wb = Workbook() ws = wb.active ws.title = "分块测试" # 添加表头 ws["A1"] = "编号" ws["B1"] = "数据" # 添加 25 行数据(应该分成 3 块:10+10+5) for i in range(1, 26): ws[f"A{i+1}"] = i ws[f"B{i+1}"] = f"数据{i}" wb.save(test_file) # 处理文件 result = await process_file_to_markdown(str(test_file)) # 验证结果 - 应该包含多个数据行块 assert result is not None assert "数据行 1-10" in result # 第一块 assert "数据行 11-20" in result # 第二块 assert "数据行 21-25" in result # 第三块 print(f"✓ Excel 分块处理成功(25行 -> 3块)") @pytest.mark.asyncio async def test_excel_duplicate_columns(self, tmp_path): """测试包含重复列名的 Excel 处理""" test_file = tmp_path / "test_duplicate_cols.xlsx" wb = Workbook() ws = wb.active ws.title = "重复列名" # 添加重复的表头 ws["A1"] = "数据" ws["B1"] = "数据" ws["C1"] = "数据" # 添加数据 ws["A2"] = "值1" ws["B2"] = "值2" ws["C2"] = "值3" wb.save(test_file) # 处理文件 result = await process_file_to_markdown(str(test_file)) # 验证结果 - 重复列名应该被重命名 assert result is not None # 检查是否包含原始数据 assert "值1" in result or "值2" in result print(f"✓ 重复列名 Excel 处理成功") @pytest.mark.asyncio async def test_excel_multiple_sheets(self, tmp_path): """测试包含多个工作表的 Excel 处理""" test_file = tmp_path / "test_multi_sheets.xlsx" wb = Workbook() # 第一个工作表 ws1 = wb.active ws1.title = "表1" ws1["A1"] = "列A" ws1["A2"] = "数据1" # 第二个工作表 ws2 = wb.create_sheet("表2") ws2["A1"] = "列B" ws2["A2"] = "数据2" wb.save(test_file) # 处理文件 result = await process_file_to_markdown(str(test_file)) # 验证结果 - 应该包含两个工作表 assert result is not None assert "表1" in result assert "表2" in result assert "数据1" in result assert "数据2" in result print(f"✓ 多工作表 Excel 处理成功") @pytest.mark.asyncio async def test_excel_with_newlines(self, tmp_path): """测试包含换行符的单元格处理""" test_file = tmp_path / "test_newlines.xlsx" wb = Workbook() ws = wb.active ws.title = "换行测试" ws["A1"] = "标题" ws["A2"] = "第一行\n第二行\n第三行" wb.save(test_file) # 处理文件 result = await process_file_to_markdown(str(test_file)) # 验证结果 - 换行符应该被替换为
assert result is not None assert "
" in result print(f"✓ 换行符处理成功(\\n ->
)") class TestJSONProcessingChanges: """测试 JSON 处理的异步变更""" @pytest.mark.asyncio async def test_json_processing(self, tmp_path): """测试 JSON 文件的异步处理""" import json test_file = tmp_path / "test.json" test_data = { "name": "测试", "items": [{"id": 1, "value": "值1"}, {"id": 2, "value": "值2"}], "nested": {"key": "嵌套数据"}, } # 写入 JSON 文件 with open(test_file, "w", encoding="utf-8") as f: json.dump(test_data, f, ensure_ascii=False) # 异步处理文件 result = await process_file_to_markdown(str(test_file)) # 验证结果 assert result is not None assert "```json" in result assert "测试" in result assert "嵌套数据" in result print(f"✓ JSON 异步处理成功") print(f"处理结果预览:\n{result[:200]}...") if __name__ == "__main__": exit_code = pytest.main([__file__, "-v", "-s", "--tb=short", "--color=yes"]) sys.exit(exit_code)