mirror of https://github.com/home-assistant/core
132 lines
4.4 KiB
Python
132 lines
4.4 KiB
Python
"""Test img_util module."""
|
|
|
|
from unittest.mock import patch
|
|
|
|
import pytest
|
|
from turbojpeg import TurboJPEG
|
|
|
|
from homeassistant.components.camera import Image
|
|
from homeassistant.components.camera.img_util import (
|
|
TurboJPEGSingleton,
|
|
find_supported_scaling_factor,
|
|
scale_jpeg_camera_image,
|
|
)
|
|
|
|
from .common import EMPTY_8_6_JPEG, mock_turbo_jpeg
|
|
|
|
EMPTY_16_12_JPEG = b"empty_16_12"
|
|
|
|
|
|
def _clear_turbojpeg_singleton():
|
|
TurboJPEGSingleton.__instance = None
|
|
|
|
|
|
def _reset_turbojpeg_singleton():
|
|
TurboJPEGSingleton.__instance = TurboJPEG()
|
|
|
|
|
|
def test_turbojpeg_singleton() -> None:
|
|
"""Verify the instance always gives back the same."""
|
|
_clear_turbojpeg_singleton()
|
|
assert TurboJPEGSingleton.instance() == TurboJPEGSingleton.instance()
|
|
|
|
|
|
def test_scale_jpeg_camera_image() -> None:
|
|
"""Test we can scale a jpeg image."""
|
|
_clear_turbojpeg_singleton()
|
|
|
|
camera_image = Image("image/jpeg", EMPTY_16_12_JPEG)
|
|
|
|
turbo_jpeg = mock_turbo_jpeg(first_width=16, first_height=12)
|
|
with patch(
|
|
"homeassistant.components.camera.img_util.TurboJPEG", return_value=False
|
|
):
|
|
TurboJPEGSingleton()
|
|
assert scale_jpeg_camera_image(camera_image, 16, 12) == camera_image.content
|
|
|
|
turbo_jpeg = mock_turbo_jpeg(first_width=16, first_height=12)
|
|
turbo_jpeg.decode_header.side_effect = OSError
|
|
with patch(
|
|
"homeassistant.components.camera.img_util.TurboJPEG", return_value=turbo_jpeg
|
|
):
|
|
TurboJPEGSingleton()
|
|
assert scale_jpeg_camera_image(camera_image, 16, 12) == camera_image.content
|
|
|
|
turbo_jpeg = mock_turbo_jpeg(first_width=16, first_height=12)
|
|
with patch(
|
|
"homeassistant.components.camera.img_util.TurboJPEG", return_value=turbo_jpeg
|
|
):
|
|
TurboJPEGSingleton()
|
|
assert scale_jpeg_camera_image(camera_image, 16, 12) == EMPTY_16_12_JPEG
|
|
|
|
turbo_jpeg = mock_turbo_jpeg(
|
|
first_width=16, first_height=12, second_width=8, second_height=6
|
|
)
|
|
with patch(
|
|
"homeassistant.components.camera.img_util.TurboJPEG", return_value=turbo_jpeg
|
|
):
|
|
TurboJPEGSingleton()
|
|
jpeg_bytes = scale_jpeg_camera_image(camera_image, 8, 6)
|
|
|
|
assert jpeg_bytes == EMPTY_8_6_JPEG
|
|
|
|
turbo_jpeg = mock_turbo_jpeg(
|
|
first_width=640, first_height=480, second_width=640, second_height=480
|
|
)
|
|
with patch(
|
|
"homeassistant.components.camera.img_util.TurboJPEG", return_value=turbo_jpeg
|
|
):
|
|
TurboJPEGSingleton()
|
|
jpeg_bytes = scale_jpeg_camera_image(camera_image, 320, 480)
|
|
|
|
assert jpeg_bytes == EMPTY_16_12_JPEG
|
|
|
|
|
|
def test_turbojpeg_load_failure() -> None:
|
|
"""Handle libjpegturbo not being installed."""
|
|
_clear_turbojpeg_singleton()
|
|
with patch(
|
|
"homeassistant.components.camera.img_util.TurboJPEG", side_effect=Exception
|
|
):
|
|
TurboJPEGSingleton()
|
|
assert TurboJPEGSingleton.instance() is False
|
|
|
|
_clear_turbojpeg_singleton()
|
|
TurboJPEGSingleton()
|
|
assert TurboJPEGSingleton.instance() is not None
|
|
|
|
|
|
SCALE_TEST_EXPECTED = [
|
|
(5782, 3946, 640, 480, (1, 8)), # Maximum scale
|
|
(1600, 1200, 640, 480, (1, 2)), # Equal scale for width and height
|
|
(1600, 1200, 1400, 1050, (7, 8)), # Equal scale for width and height
|
|
(1600, 1200, 1200, 900, (3, 4)), # Equal scale for width and height
|
|
(1600, 1200, 1000, 750, (5, 8)), # Equal scale for width and height
|
|
(1600, 1200, 600, 450, (3, 8)), # Equal scale for width and height
|
|
(1600, 1200, 400, 300, (1, 4)), # Equal scale for width and height
|
|
(1600, 1200, 401, 300, (3, 8)), # Width is just a little to big, next size up
|
|
(640, 480, 330, 200, (5, 8)), # Preserve width clarity
|
|
(640, 480, 300, 260, (5, 8)), # Preserve height clarity
|
|
(640, 480, 1200, 480, None), # Request larger width - no scaling
|
|
(640, 480, 640, 480, None), # Request same - no scaling
|
|
(640, 480, 640, 270, None), # Request smaller height - no scaling
|
|
(640, 480, 320, 480, None), # Request smaller width - no scaling
|
|
]
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("image_width", "image_height", "input_width", "input_height", "scaling_factor"),
|
|
SCALE_TEST_EXPECTED,
|
|
)
|
|
def test_find_supported_scaling_factor(
|
|
image_width, image_height, input_width, input_height, scaling_factor
|
|
) -> None:
|
|
"""Test we always get an image of at least the size we ask if its big enough."""
|
|
|
|
assert (
|
|
find_supported_scaling_factor(
|
|
image_width, image_height, input_width, input_height
|
|
)
|
|
== scaling_factor
|
|
)
|