📝 新增完整项目文档、测试套件与构建配置
This commit is contained in:
227
tests/test_optimization.py
Normal file
227
tests/test_optimization.py
Normal file
@@ -0,0 +1,227 @@
|
||||
"""Tests for imageOptimization function."""
|
||||
|
||||
import pytest
|
||||
from pathlib import Path
|
||||
from unittest.mock import Mock, MagicMock, patch
|
||||
from PIL import Image
|
||||
import numpy as np
|
||||
from pptopic.lib import imageOptimization
|
||||
|
||||
|
||||
class TestImageOptimization:
|
||||
"""Test imageOptimization function."""
|
||||
|
||||
@patch('pptopic.lib.Image.open')
|
||||
@patch('pptopic.lib.cv2.cvtColor')
|
||||
@patch('pptopic.lib.cv2.resize')
|
||||
@patch('pptopic.lib.subprocess.run')
|
||||
@patch('pptopic.lib.lastFile')
|
||||
def test_image_optimization_with_file_path(self, mock_last_file, mock_subprocess,
|
||||
mock_resize, mock_cvtcolor, mock_open, tmp_path):
|
||||
"""Test imageOptimization with file path input."""
|
||||
mock_img = MagicMock()
|
||||
mock_img.size = (100, 100)
|
||||
mock_img.mode = 'RGB'
|
||||
mock_open.return_value = mock_img
|
||||
|
||||
mock_array = np.array([[[255, 0, 0]]])
|
||||
mock_cvtcolor.return_value = mock_array
|
||||
|
||||
mock_resized = np.array([[[255, 0, 0]]])
|
||||
mock_resize.return_value = mock_resized
|
||||
|
||||
mock_pil_img = MagicMock()
|
||||
with patch('pptopic.lib.Image.fromarray', return_value=mock_pil_img):
|
||||
with patch('pptopic.lib.Image.open', return_value=mock_img):
|
||||
mock_last_file.return_value = tmp_path / "optimized.png"
|
||||
|
||||
result = imageOptimization(tmp_path / "test.png")
|
||||
|
||||
assert result is not None
|
||||
|
||||
@patch('pptopic.lib.cv2.cvtColor')
|
||||
@patch('pptopic.lib.cv2.resize')
|
||||
@patch('pptopic.lib.subprocess.run')
|
||||
@patch('pptopic.lib.lastFile')
|
||||
def test_image_optimization_with_pil_image(self, mock_last_file, mock_subprocess,
|
||||
mock_resize, mock_cvtcolor, tmp_path):
|
||||
"""Test imageOptimization with PIL Image input."""
|
||||
mock_img = MagicMock()
|
||||
mock_img.size = (100, 100)
|
||||
mock_img.mode = 'RGB'
|
||||
|
||||
mock_array = np.array([[[255, 0, 0]]])
|
||||
mock_cvtcolor.return_value = mock_array
|
||||
|
||||
mock_resized = np.array([[[255, 0, 0]]])
|
||||
mock_resize.return_value = mock_resized
|
||||
|
||||
mock_pil_img = MagicMock()
|
||||
with patch('pptopic.lib.Image.fromarray', return_value=mock_pil_img):
|
||||
with patch('pptopic.lib.Image.open', return_value=mock_img):
|
||||
mock_last_file.return_value = tmp_path / "optimized.png"
|
||||
|
||||
result = imageOptimization(mock_img)
|
||||
|
||||
assert result is not None
|
||||
|
||||
@patch('pptopic.lib.Image.open')
|
||||
@patch('pptopic.lib.cv2.cvtColor')
|
||||
@patch('pptopic.lib.cv2.resize')
|
||||
@patch('pptopic.lib.subprocess.run')
|
||||
@patch('pptopic.lib.shutil.copyfile')
|
||||
def test_image_optimization_with_save_file(self, mock_copyfile, mock_subprocess,
|
||||
mock_resize, mock_cvtcolor, mock_open, tmp_path):
|
||||
"""Test imageOptimization with saveFile parameter."""
|
||||
mock_img = MagicMock()
|
||||
mock_img.size = (100, 100)
|
||||
mock_img.mode = 'RGB'
|
||||
mock_open.return_value = mock_img
|
||||
|
||||
mock_array = np.array([[[255, 0, 0]]])
|
||||
mock_cvtcolor.return_value = mock_array
|
||||
|
||||
mock_resized = np.array([[[255, 0, 0]]])
|
||||
mock_resize.return_value = mock_resized
|
||||
|
||||
mock_pil_img = MagicMock()
|
||||
with patch('pptopic.lib.Image.fromarray', return_value=mock_pil_img):
|
||||
with patch('pptopic.lib.lastFile') as mock_last_file:
|
||||
mock_last_file.return_value = tmp_path / "optimized.png"
|
||||
|
||||
result = imageOptimization(tmp_path / "test.png", saveFile=tmp_path / "output.png")
|
||||
|
||||
assert result is None
|
||||
mock_copyfile.assert_called_once()
|
||||
|
||||
@patch('pptopic.lib.Image.open')
|
||||
@patch('pptopic.lib.cv2.cvtColor')
|
||||
@patch('pptopic.lib.cv2.resize')
|
||||
@patch('pptopic.lib.subprocess.run')
|
||||
@patch('pptopic.lib.lastFile')
|
||||
def test_image_optimization_with_max_width(self, mock_last_file, mock_subprocess,
|
||||
mock_resize, mock_cvtcolor, mock_open, tmp_path):
|
||||
"""Test imageOptimization with max_width parameter."""
|
||||
mock_img = MagicMock()
|
||||
mock_img.size = (200, 100)
|
||||
mock_img.mode = 'RGB'
|
||||
mock_open.return_value = mock_img
|
||||
|
||||
mock_array = np.zeros((100, 200, 3), dtype=np.uint8)
|
||||
mock_cvtcolor.return_value = mock_array
|
||||
|
||||
mock_resized = np.zeros((50, 100, 3), dtype=np.uint8)
|
||||
mock_resize.return_value = mock_resized
|
||||
|
||||
mock_pil_img = MagicMock()
|
||||
with patch('pptopic.lib.Image.fromarray', return_value=mock_pil_img):
|
||||
with patch('pptopic.lib.Image.open', return_value=mock_img):
|
||||
mock_last_file.return_value = tmp_path / "optimized.png"
|
||||
|
||||
result = imageOptimization(tmp_path / "test.png", max_width=100)
|
||||
|
||||
mock_resize.assert_called_once()
|
||||
assert result is not None
|
||||
|
||||
@patch('pptopic.lib.Image.open')
|
||||
@patch('pptopic.lib.cv2.cvtColor')
|
||||
@patch('pptopic.lib.cv2.resize')
|
||||
@patch('pptopic.lib.subprocess.run')
|
||||
@patch('pptopic.lib.lastFile')
|
||||
def test_image_optimization_with_max_height(self, mock_last_file, mock_subprocess,
|
||||
mock_resize, mock_cvtcolor, mock_open, tmp_path):
|
||||
"""Test imageOptimization with max_height parameter."""
|
||||
mock_img = MagicMock()
|
||||
mock_img.size = (100, 200)
|
||||
mock_img.mode = 'RGB'
|
||||
mock_open.return_value = mock_img
|
||||
|
||||
mock_array = np.zeros((200, 100, 3), dtype=np.uint8)
|
||||
mock_cvtcolor.return_value = mock_array
|
||||
|
||||
mock_resized = np.zeros((100, 50, 3), dtype=np.uint8)
|
||||
mock_resize.return_value = mock_resized
|
||||
|
||||
mock_pil_img = MagicMock()
|
||||
with patch('pptopic.lib.Image.fromarray', return_value=mock_pil_img):
|
||||
with patch('pptopic.lib.Image.open', return_value=mock_img):
|
||||
mock_last_file.return_value = tmp_path / "optimized.png"
|
||||
|
||||
result = imageOptimization(tmp_path / "test.png", max_height=100)
|
||||
|
||||
mock_resize.assert_called_once()
|
||||
assert result is not None
|
||||
|
||||
@patch('pptopic.lib.Image.open')
|
||||
@patch('pptopic.lib.cv2.cvtColor')
|
||||
@patch('pptopic.lib.cv2.resize')
|
||||
@patch('pptopic.lib.subprocess.run')
|
||||
@patch('pptopic.lib.lastFile')
|
||||
def test_image_optimization_with_fractional_width(self, mock_last_file, mock_subprocess,
|
||||
mock_resize, mock_cvtcolor, mock_open, tmp_path):
|
||||
"""Test imageOptimization with fractional max_width (< 1)."""
|
||||
mock_img = MagicMock()
|
||||
mock_img.size = (200, 100)
|
||||
mock_img.mode = 'RGB'
|
||||
mock_open.return_value = mock_img
|
||||
|
||||
mock_array = np.zeros((100, 200, 3), dtype=np.uint8)
|
||||
mock_cvtcolor.return_value = mock_array
|
||||
|
||||
mock_resized = np.zeros((50, 100, 3), dtype=np.uint8)
|
||||
mock_resize.return_value = mock_resized
|
||||
|
||||
mock_pil_img = MagicMock()
|
||||
with patch('pptopic.lib.Image.fromarray', return_value=mock_pil_img):
|
||||
with patch('pptopic.lib.Image.open', return_value=mock_img):
|
||||
mock_last_file.return_value = tmp_path / "optimized.png"
|
||||
|
||||
result = imageOptimization(tmp_path / "test.png", max_width=0.5)
|
||||
|
||||
mock_resize.assert_called_once()
|
||||
assert result is not None
|
||||
|
||||
@patch('pptopic.lib.Image.open')
|
||||
@patch('pptopic.lib.cv2.cvtColor')
|
||||
@patch('pptopic.lib.subprocess.run')
|
||||
@patch('pptopic.lib.lastFile')
|
||||
def test_image_optimization_without_engine(self, mock_last_file, mock_subprocess,
|
||||
mock_cvtcolor, mock_open, tmp_path):
|
||||
"""Test imageOptimization with engine=None."""
|
||||
mock_img = MagicMock()
|
||||
mock_img.size = (100, 100)
|
||||
mock_img.mode = 'RGB'
|
||||
mock_open.return_value = mock_img
|
||||
|
||||
mock_array = np.array([[[255, 0, 0]]])
|
||||
mock_cvtcolor.return_value = mock_array
|
||||
|
||||
mock_pil_img = MagicMock()
|
||||
with patch('pptopic.lib.Image.fromarray', return_value=mock_pil_img):
|
||||
with patch('pptopic.lib.Image.open', return_value=mock_img):
|
||||
mock_last_file.return_value = tmp_path / "optimized.png"
|
||||
|
||||
result = imageOptimization(tmp_path / "test.png", engine=None)
|
||||
|
||||
mock_subprocess.assert_not_called()
|
||||
assert result is not None
|
||||
|
||||
@patch('pptopic.lib.Image.open')
|
||||
@patch('pptopic.lib.cv2.cvtColor')
|
||||
@patch('pptopic.lib.subprocess.run')
|
||||
def test_image_optimization_engine_failure(self, mock_subprocess, mock_cvtcolor, mock_open):
|
||||
"""Test imageOptimization when engine subprocess fails."""
|
||||
mock_img = MagicMock()
|
||||
mock_img.size = (100, 100)
|
||||
mock_img.mode = 'RGB'
|
||||
mock_open.return_value = mock_img
|
||||
|
||||
mock_array = np.array([[[255, 0, 0]]])
|
||||
mock_cvtcolor.return_value = mock_array
|
||||
|
||||
mock_subprocess.side_effect = Exception("Engine not found")
|
||||
|
||||
mock_pil_img = MagicMock()
|
||||
with patch('pptopic.lib.Image.fromarray', return_value=mock_pil_img):
|
||||
with pytest.raises(Exception):
|
||||
imageOptimization("test.png", engine="pngquant", engine_conf="--quality=85")
|
||||
Reference in New Issue
Block a user