arm-tabular-parser/api/tests/unit/parser/test_reader_number_format.py
Andrey Epifancev 0c65e92ffb readers: числовой формат числовых ячеек в Cell (#42)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 17:07:15 +04:00

76 lines
3.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Числовой формат числовых ячеек в `Cell.number_format` (#42): xlsx синтетикой, xls — реальным файлом из fixtures."""
import datetime
import io
from pathlib import Path
import openpyxl
import pytest
from src.parser.readers import read_book
from src.parser.readers import xlsb as xlsb_reader
from src.parser.readers._common import make_cell
from tests.unit.parser.test_readers import _FakeXlsbBook, _zip_with
FILLED_CELLS = 6
UNAGRANDE_XLS = "statements-xlsx/unagrande-group/2025-Q3/ББ. Лист 2 3кв.25.xls"
def _xlsx() -> bytes:
book = openpyxl.Workbook()
ws = book.active
assert ws is not None
ws["A1"] = 10741981390
ws["A1"].number_format = "#,##0,"
ws["A2"] = 586260.26
ws["A2"].number_format = "0,"
ws["A3"] = 5
ws["A4"] = 7
ws["A4"].number_format = "General"
ws["A5"] = "текст"
ws["A5"].number_format = "0,"
ws["A6"] = datetime.datetime(2025, 9, 30)
ws["A6"].number_format = "dd.mm.yyyy"
out = io.BytesIO()
book.save(out)
return out.getvalue()
def test_xlsx_number_format_is_kept_for_numbers_only() -> None:
sheets, _ = read_book(_xlsx(), "XLSX")
sheet = sheets[0]
assert sheet.cell(1, 1).number_format == "#,##0,"
assert sheet.cell(2, 1).number_format == "0,"
assert sheet.cell(3, 1).number_format is None # General по умолчанию
assert sheet.cell(4, 1).number_format is None # явный General
assert sheet.cell(5, 1).number_format is None # текст
assert sheet.cell(6, 1).kind == "date"
assert sheet.cell(6, 1).number_format is None # дата
assert len(sheet.cells) == FILLED_CELLS # разреженность: Cell только у непустых
def test_make_cell_number_format_rules() -> None:
assert make_cell(1.5, number_format="GENERAL").number_format is None # type: ignore[union-attr]
assert make_cell(1.5, number_format="").number_format is None # type: ignore[union-attr]
assert make_cell(1.5, number_format="0,").number_format == "0," # type: ignore[union-attr]
assert make_cell("x", number_format="0,").number_format is None # type: ignore[union-attr]
assert make_cell(datetime.datetime(2025, 1, 1), number_format="0,").number_format is None # type: ignore[union-attr]
@pytest.mark.fixtures
def test_xls_number_format_is_read(fixtures_dir: Path) -> None:
sheets, _ = read_book((fixtures_dir / UNAGRANDE_XLS).read_bytes(), "XLS")
formats = {cell.number_format for sheet in sheets for cell in sheet.cells.values() if cell.kind == "number"}
assert {"#,##0,", "0,", '[=0]"-"'} <= formats
assert all(cell.number_format is None for sheet in sheets for cell in sheet.cells.values() if cell.kind != "number")
def test_xlsb_cells_have_no_number_format(monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setattr(xlsb_reader.pyxlsb, "open_workbook", lambda _stream: _FakeXlsbBook())
sheets, _ = read_book(_zip_with("xl/workbook.bin"), "XLSB")
assert all(cell.number_format is None for cell in sheets[0].cells.values())