File size: 2,767 Bytes
2857cf3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
85
86
87
88
89
90
91
from __future__ import annotations

from pathlib import Path

import pandas as pd
from openpyxl import Workbook, load_workbook
from openpyxl.worksheet.worksheet import Worksheet
from PIL import Image as PILImage

from kneiff.utils.excel import (
    freeze_sheet_panes,
    insert_image,
    pixels_to_column_width,
    pixels_to_row_height,
    read_excel_dataframes,
    set_column_width,
    write_excel_dataframes,
)


def _touch(path: Path, *, size: tuple[int, int] = (24, 12)) -> None:
    path.parent.mkdir(parents=True, exist_ok=True)
    PILImage.new("RGB", size, color="white").save(path, format="PNG")


def test_freeze_sheet_panes_sets_expected_coordinates() -> None:
    workbook = Workbook()
    worksheet = workbook.active

    freeze_sheet_panes(worksheet, frozen_rows=1, frozen_columns=0)
    assert worksheet.freeze_panes == "A2"

    freeze_sheet_panes(worksheet, frozen_rows=1, frozen_columns=1)
    assert worksheet.freeze_panes == "B2"

    freeze_sheet_panes(worksheet, frozen_rows=0, frozen_columns=0)
    assert worksheet.freeze_panes is None


def test_pixel_conversions_match_excel_layout_helpers() -> None:
    assert pixels_to_row_height(164) == 123
    assert pixels_to_column_width(168) == 23.29
    assert pixels_to_column_width(328) == 46.14


def test_write_excel_dataframes_runs_style_callback(tmp_path: Path) -> None:
    workbook_path = tmp_path / "styled.xlsx"
    seen_sheets: list[str] = []

    def style_sheet(
        sheet_name: str,
        worksheet: Worksheet,
        dataframe: pd.DataFrame,
    ) -> None:
        seen_sheets.append(sheet_name)
        assert list(dataframe.columns) == ["name"]
        freeze_sheet_panes(worksheet, frozen_rows=1, frozen_columns=1)
        set_column_width(worksheet, column_index=1, width=12)

    write_excel_dataframes(
        workbook_path,
        {"images": pd.DataFrame([{"name": "cover.jpg"}])},
        style_sheet=style_sheet,
    )

    assert seen_sheets == ["images"]
    workbook = load_workbook(workbook_path)
    try:
        worksheet = workbook["images"]
        assert worksheet.freeze_panes == "B2"
        assert worksheet.column_dimensions["A"].width == 12
    finally:
        workbook.close()

    dataframes = read_excel_dataframes(workbook_path)
    assert list(dataframes) == ["images"]
    assert dataframes["images"].to_dict("records") == [{"name": "cover.jpg"}]


def test_insert_image_returns_dimensions(tmp_path: Path) -> None:
    image_path = tmp_path / "image.png"
    _touch(image_path, size=(24, 12))
    workbook = Workbook()
    worksheet = workbook.active

    dimensions = insert_image(worksheet, image_path=image_path, cell="A2")

    assert dimensions.width == 24
    assert dimensions.height == 12
    assert len(worksheet._images) == 1