File size: 2,868 Bytes
0e6887b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
"""FileService 结构化摄入测试(任务 16)。

覆盖:xlsx 多子表切分 + 空单元格保留(无列错位);csv 网格;缺库降级安全。
"""

from __future__ import annotations

import os
import tempfile

import pytest

from services.file_service import FileService, ParsedDocument, TableGrid


def _make_sl0010_xlsx(path):
    from openpyxl import Workbook
    wb = Workbook()
    ws = wb.active
    ws.title = "Sheet1"
    # 物理特性子表
    ws.append(["物理特性检测结果"])
    ws.append(["批号", "涂布厚度/mm", "膜厚/mm", "溶化时限/s"])
    ws.append(["SL-0010-20μg", 0.5, 0.05, 60])
    ws.append(["SL-0010-40μg", None, 0.07, 74])   # 涂布厚度空单元格
    ws.append([])  # 空行分隔
    # 有关物质子表
    ws.append(["有关物质检测结果"])
    ws.append(["样品名称", "保留时间min", "总杂%"])
    ws.append(["SL-0010-20μg", 25.44, 0.0])
    wb.save(path)


def test_excel_structured_preserves_empty_cells_and_segments():
    fd, path = tempfile.mkstemp(suffix=".xlsx")
    os.close(fd)
    try:
        _make_sl0010_xlsx(path)
        doc = FileService().parse_structured(path)
        assert isinstance(doc, ParsedDocument)
        # 两张子表被切分
        assert len(doc.tables) == 2
        phys = doc.tables[0]
        assert phys.title == "物理特性检测结果"
        # 数据行:40μg 行的涂布厚度保留为 None(不塌缩),列对齐
        row40 = [r for r in phys.rows if r and r[0] == "SL-0010-40μg"][0]
        assert row40[1] is None        # 涂布厚度空
        assert row40[2] == "0.07"      # 膜厚仍在第 2 列
    finally:
        os.remove(path)


def test_csv_structured_grid():
    fd, path = tempfile.mkstemp(suffix=".csv")
    os.close(fd)
    try:
        with open(path, "w", encoding="utf-8-sig", newline="") as f:
            f.write("批号,膜厚,水分\nSL-0010-20μg,0.05,5.3\n")
        doc = FileService().parse_structured(path)
        assert len(doc.tables) == 1
        assert doc.tables[0].rows[0] == ["批号", "膜厚", "水分"]
    finally:
        os.remove(path)


def test_structured_degrades_safely_when_format_unavailable():
    # 用一个不支持依赖的格式名模拟:构造一个 import_checker 永远返回 False。
    svc = FileService(import_checker=lambda name: False)
    fd, path = tempfile.mkstemp(suffix=".xlsx")
    os.close(fd)
    try:
        _make_sl0010_xlsx(path)
        doc = svc.parse_structured(path)
        # 依赖不可用 → 不抛异常,返回 ParsedDocument(tables 可能为空)
        assert isinstance(doc, ParsedDocument)
        assert doc.tables == []
    finally:
        os.remove(path)


def test_pdf_dependency_is_pymupdf():
    from services.file_service import _FORMAT_DEPENDENCY, FORMAT_PDF
    assert _FORMAT_DEPENDENCY[FORMAT_PDF] == "fitz"