feat(lib): 添加批量图片优化功能与实时进度显示

- 新增 `batchImageOptimization` 函数支持批量处理图片
- 为图片优化添加 spinner 进度指示器和实时计时显示
- 更新版本号至 0.3.2
This commit is contained in:
2026-06-18 16:17:38 +08:00
parent ffcb2801b2
commit 97b30ace84
9 changed files with 553 additions and 479 deletions

View File

@@ -1,150 +1,102 @@
"""Tests for convertPPT class."""
import pytest
from pathlib import Path
from unittest.mock import Mock, MagicMock, patch
from unittest.mock import MagicMock, patch
import pytest
from pptopic.lib import convertPPT
class TestConvertPPTClass:
"""Test convertPPT class initialization and properties."""
class TestConvertPPT:
"""Test convertPPT class."""
def test_ttypes_mapping(self):
"""Test that TTYPES mapping is correct."""
assert convertPPT.TTYPES["JPG"] == 17
assert convertPPT.TTYPES["PNG"] == 18
assert convertPPT.TTYPES["PDF"] == 32
assert convertPPT.TTYPES["XPS"] == 33
TTYPE_VALUES = [("JPG", 17), ("PNG", 18), ("PDF", 32), ("XPS", 33)]
@patch('pptopic.lib.sys.platform', 'win32')
def test_init_with_valid_file(self, tmp_path):
"""Test initialization with a valid file path."""
@pytest.mark.parametrize("ttype,expected", TTYPE_VALUES)
def test_ttypes_mapping(self, ttype, expected):
assert convertPPT.TTYPES[ttype] == expected
@pytest.mark.parametrize("as_path", [False, True])
@patch("pptopic.lib.sys.platform", "win32")
def test_init_valid(self, as_path, tmp_path):
test_file = tmp_path / "test.pptx"
test_file.touch()
with patch('pptopic.lib.wcc.Dispatch') as mock_dispatch:
mock_app = MagicMock()
mock_dispatch.return_value = mock_app
if as_path:
test_file = Path(test_file)
with patch("pptopic.lib.wcc.Dispatch"):
ppt = convertPPT(test_file, trans="JPG")
assert ppt.savetype == "JPG"
mock_dispatch.assert_called_once_with('PowerPoint.Application')
@patch('pptopic.lib.sys.platform', 'win32')
def test_init_with_path_object(self, tmp_path):
"""Test initialization with Path object."""
test_file = tmp_path / "test.pptx"
test_file.touch()
with patch('pptopic.lib.wcc.Dispatch'):
ppt = convertPPT(Path(test_file), trans="PNG")
assert ppt.savetype == "PNG"
@patch('pptopic.lib.sys.platform', 'win32')
def test_init_with_nonexistent_file(self):
"""Test initialization with nonexistent file raises FileNotFoundError."""
@patch("pptopic.lib.sys.platform", "win32")
def test_init_nonexistent_file(self):
with pytest.raises(FileNotFoundError, match="File not found"):
convertPPT("nonexistent.pptx")
@patch('pptopic.lib.sys.platform', 'win32')
def test_init_with_invalid_trans_type(self, tmp_path):
"""Test initialization with invalid save type raises ValueError."""
@patch("pptopic.lib.sys.platform", "win32")
def test_init_invalid_trans_type(self, tmp_path):
test_file = tmp_path / "test.pptx"
test_file.touch()
with pytest.raises(ValueError, match="Save type is not supported"):
convertPPT(test_file, trans="BMP")
@patch('pptopic.lib.sys.platform', 'win32')
def test_init_with_case_insensitive_trans(self, tmp_path):
"""Test that trans parameter is case insensitive."""
@pytest.mark.parametrize("ttype,expected", [("jpg", "JPG"), ("Pdf", "PDF")])
@patch("pptopic.lib.sys.platform", "win32")
def test_init_case_insensitive_trans(self, ttype, expected, tmp_path):
test_file = tmp_path / "test.pptx"
test_file.touch()
with patch('pptopic.lib.wcc.Dispatch'):
ppt = convertPPT(test_file, trans="jpg")
assert ppt.savetype == "JPG"
ppt = convertPPT(test_file, trans="Pdf")
assert ppt.savetype == "PDF"
with patch("pptopic.lib.wcc.Dispatch"):
ppt = convertPPT(test_file, trans=ttype)
assert ppt.savetype == expected
class TestConvertPTTNonWindows:
"""Test convertPPT behavior on non-Windows systems."""
@patch('pptopic.lib.sys.platform', 'linux')
def test_init_on_non_windows_raises_error(self):
"""Test that initialization on non-Windows raises SystemError."""
@patch("pptopic.lib.sys.platform", "linux")
def test_init_non_windows_raises_error(self):
with pytest.raises(SystemError, match="Only support Windows system"):
convertPPT("test.pptx")
class TestConvertPPTContextManager:
"""Test convertPPT as context manager."""
@patch('pptopic.lib.sys.platform', 'win32')
def test_context_manager_enter_exit(self, tmp_path):
"""Test __enter__ and __exit__ methods."""
@patch("pptopic.lib.sys.platform", "win32")
def test_context_manager(self, tmp_path):
test_file = tmp_path / "test.pptx"
test_file.touch()
with patch('pptopic.lib.wcc.Dispatch') as mock_dispatch:
with patch("pptopic.lib.wcc.Dispatch") as mock_dispatch:
mock_app = MagicMock()
mock_dispatch.return_value = mock_app
with convertPPT(test_file) as ppt:
assert ppt.savetype == "JPG"
mock_app.Quit.assert_called_once()
class TestConvertPPTSaveAs:
"""Test saveAs method."""
@patch('pptopic.lib.sys.platform', 'win32')
def test_saveas_default(self, tmp_path):
"""Test saveAs with default parameter."""
@pytest.mark.parametrize(
"save_as,expected",
[(None, "JPG"), ("PDF", "PDF")],
ids=["default_jpg", "explicit_pdf"],
)
@patch("pptopic.lib.sys.platform", "win32")
def test_saveas(self, save_as, expected, tmp_path):
test_file = tmp_path / "test.pptx"
test_file.touch()
with patch('pptopic.lib.wcc.Dispatch'):
with patch("pptopic.lib.wcc.Dispatch"):
ppt = convertPPT(test_file, trans="PNG")
ppt.saveAs()
assert ppt.savetype == "JPG"
ppt.saveAs(save_as)
assert ppt.savetype == expected
@patch('pptopic.lib.sys.platform', 'win32')
def test_saveas_with_valid_type(self, tmp_path):
"""Test saveAs with valid save type."""
@patch("pptopic.lib.sys.platform", "win32")
def test_saveas_invalid_type(self, tmp_path):
test_file = tmp_path / "test.pptx"
test_file.touch()
with patch('pptopic.lib.wcc.Dispatch'):
ppt = convertPPT(test_file, trans="JPG")
ppt.saveAs("PDF")
assert ppt.savetype == "PDF"
@patch('pptopic.lib.sys.platform', 'win32')
def test_saveas_with_invalid_type(self, tmp_path):
"""Test saveAs with invalid save type raises ValueError."""
test_file = tmp_path / "test.pptx"
test_file.touch()
with patch('pptopic.lib.wcc.Dispatch'):
ppt = convertPPT(test_file, trans="JPG")
with patch("pptopic.lib.wcc.Dispatch"):
ppt = convertPPT(test_file)
with pytest.raises(ValueError, match="Save type is not supported"):
ppt.saveAs("BMP")
class TestConvertPTTOpenClassmethod:
"""Test open class method."""
@patch('pptopic.lib.sys.platform', 'win32')
@patch("pptopic.lib.sys.platform", "win32")
def test_open_classmethod(self, tmp_path):
"""Test open class method creates instance."""
test_file = tmp_path / "test.pptx"
test_file.touch()
with patch('pptopic.lib.wcc.Dispatch'):
with patch("pptopic.lib.wcc.Dispatch"):
ppt = convertPPT.open(test_file, trans="PNG")
assert ppt.savetype == "PNG"
assert isinstance(ppt, convertPPT)