- 新增 `batchImageOptimization` 函数支持批量处理图片 - 为图片优化添加 spinner 进度指示器和实时计时显示 - 更新版本号至 0.3.2
124 lines
4.9 KiB
Python
124 lines
4.9 KiB
Python
"""Tests for PPT_longPic function."""
|
|
|
|
from pathlib import Path
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
import pytest
|
|
|
|
from pptopic.lib import PPT_longPic
|
|
|
|
|
|
def _make_img_mocks(tmp_path, num_images=1):
|
|
"""Build reusable mock objects for PPT_longPic tests.
|
|
|
|
Returns (img_paths, mock_img, mock_canvas):
|
|
- img_paths: real Path objects so ``sorted()`` works
|
|
- mock_img: PIL Image mock with .size, .width, .height, .resize
|
|
- mock_canvas: PIL Image.new mock
|
|
"""
|
|
img_paths = [tmp_path / f"slide{i}.jpg" for i in range(1, num_images + 1)]
|
|
mock_img = MagicMock()
|
|
mock_img.mode = "RGB"
|
|
mock_img.size = (100, 100)
|
|
mock_img.width = 100
|
|
mock_img.height = 100
|
|
mock_img.resize.return_value = mock_img
|
|
mock_canvas = MagicMock()
|
|
return img_paths, mock_img, mock_canvas
|
|
|
|
|
|
class TestPPTLongPic:
|
|
"""Test PPT_longPic function."""
|
|
|
|
# -- width variations --------------------------------------------------
|
|
|
|
@pytest.mark.parametrize(
|
|
"width,expected_size",
|
|
[
|
|
(None, (100, 100)), # no scaling → uses img.size
|
|
(50, (50, 50)), # pixel width → (w, h*w//W)
|
|
("50%", (50, 50)), # percentage → half
|
|
],
|
|
ids=["none", "pixel", "percentage"],
|
|
)
|
|
@patch("pptopic.lib.convertPPT")
|
|
def test_width_variations(self, mock_convert_ppt, width, expected_size, tmp_path):
|
|
"""PPT_longPic handles None / pixel / percentage width correctly."""
|
|
img_paths, mock_img, mock_canvas = _make_img_mocks(tmp_path)
|
|
|
|
mock_convert_ppt.return_value.__enter__.return_value = MagicMock()
|
|
|
|
with patch("pptopic.lib.Path.glob", return_value=img_paths):
|
|
with patch("pptopic.lib.Image.open") as mock_open:
|
|
mock_open.return_value.__enter__.return_value = mock_img
|
|
with patch("pptopic.lib.Image.new", return_value=mock_canvas):
|
|
PPT_longPic(tmp_path / "test.pptx", width=width, saveto=tmp_path)
|
|
|
|
mock_canvas.save.assert_called_once()
|
|
|
|
# -- saveName / saveto variations -------------------------------------
|
|
|
|
@pytest.mark.parametrize(
|
|
"save_name,saveto",
|
|
[
|
|
(None, None), # defaults: JPG, ppt parent dir
|
|
("output.jpg", None), # named, ppt parent dir
|
|
(None, "."), # default name, custom dir
|
|
],
|
|
ids=["defaults", "named", "custom_dir"],
|
|
)
|
|
@patch("pptopic.lib.convertPPT")
|
|
def test_save_params(self, mock_convert_ppt, save_name, saveto, tmp_path):
|
|
"""PPT_longPic handles saveName / saveto combinations."""
|
|
img_paths, mock_img, mock_canvas = _make_img_mocks(tmp_path)
|
|
|
|
mock_convert_ppt.return_value.__enter__.return_value = MagicMock()
|
|
|
|
with patch("pptopic.lib.Path.glob", return_value=img_paths):
|
|
with patch("pptopic.lib.Image.open") as mock_open:
|
|
mock_open.return_value.__enter__.return_value = mock_img
|
|
with patch("pptopic.lib.Image.new", return_value=mock_canvas):
|
|
PPT_longPic(
|
|
tmp_path / "test.pptx",
|
|
saveName=save_name,
|
|
saveto=saveto if saveto else tmp_path,
|
|
)
|
|
|
|
mock_canvas.save.assert_called_once()
|
|
|
|
# -- error paths -------------------------------------------------------
|
|
|
|
def test_invalid_image_type(self, tmp_path):
|
|
ppt_file = tmp_path / "test.pptx"
|
|
ppt_file.touch()
|
|
with pytest.raises(ValueError, match="Unable to save this type"):
|
|
PPT_longPic(ppt_file, saveName="output.bmp")
|
|
|
|
@patch("pptopic.lib.convertPPT")
|
|
def test_no_images_generated(self, mock_convert_ppt, tmp_path):
|
|
ppt_file = tmp_path / "test.pptx"
|
|
ppt_file.touch()
|
|
mock_convert_ppt.return_value.__enter__.return_value = MagicMock()
|
|
|
|
with patch("pptopic.lib.Path.glob", return_value=[]):
|
|
with pytest.raises(ValueError, match="No images generated"):
|
|
PPT_longPic(ppt_file)
|
|
|
|
# -- multiple images ---------------------------------------------------
|
|
|
|
@patch("pptopic.lib.convertPPT")
|
|
def test_multiple_images(self, mock_convert_ppt, tmp_path):
|
|
"""PPT_longPic pastes every slide into the canvas."""
|
|
img_paths, mock_img, mock_canvas = _make_img_mocks(tmp_path, num_images=3)
|
|
|
|
mock_convert_ppt.return_value.__enter__.return_value = MagicMock()
|
|
|
|
with patch("pptopic.lib.Path.glob", return_value=img_paths):
|
|
with patch("pptopic.lib.Image.open") as mock_open:
|
|
mock_open.return_value.__enter__.return_value = mock_img
|
|
with patch("pptopic.lib.Image.new", return_value=mock_canvas):
|
|
PPT_longPic(tmp_path / "test.pptx", saveto=tmp_path)
|
|
|
|
assert mock_canvas.paste.call_count == 3
|
|
mock_canvas.save.assert_called_once()
|