Files
pptopic/tests/test_optimization.py

228 lines
9.4 KiB
Python

"""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")