Skip to content

Commit 8dcc69e

Browse files
committed
Replace _assert_image_operated
1 parent 9f6d506 commit 8dcc69e

File tree

2 files changed

+86
-91
lines changed

2 files changed

+86
-91
lines changed

.github/workflows/ci.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ jobs:
5252
- if: ${{ env.IS_MAIN_PYTHON != 'true' }}
5353
name: Test without coverage
5454
run: |
55-
poetry install --extras=autobpm --extras=lyrics
55+
poetry install --extras=autobpm --extras=lyrics --extras=embedart
5656
poe test
5757
5858
- if: ${{ env.IS_MAIN_PYTHON == 'true' }}

test/plugins/test_art.py

Lines changed: 85 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -863,137 +863,132 @@ def test_fetch_art_if_imported_file_deleted(self):
863863
assert self.album.art_filepath.exists()
864864

865865

866-
IMAGE_PATH = os.path.join(_common.RSRC, b"abbey-similar.jpg")
867-
IMAGE_SIZE = os.stat(util.syspath(IMAGE_PATH)).st_size
866+
class AlbumArtOperationTestCase(UseThePlugin):
867+
"""Base test case for album art operations.
868868
869+
Provides common setup for testing album art processing operations by setting
870+
up a mock filesystem source that returns a predefined test image.
871+
"""
869872

870-
def fs_source_get(_self, album, settings, paths):
871-
if paths:
872-
yield fetchart.Candidate(logger, source_name=_self.ID, path=IMAGE_PATH)
873+
IMAGE_PATH = os.path.join(_common.RSRC, b"abbey-similar.jpg")
874+
IMAGE_FILESIZE = os.stat(util.syspath(IMAGE_PATH)).st_size
875+
IMAGE_WIDTH = 500
876+
IMAGE_HEIGHT = 490
877+
IMAGE_WIDTH_HEIGHT_DIFF = IMAGE_WIDTH - IMAGE_HEIGHT
873878

879+
@classmethod
880+
def setUpClass(cls):
881+
super().setUpClass()
874882

875-
@patch("beetsplug.fetchart.FileSystem.get", fs_source_get)
876-
class ArtForAlbumTest(UseThePlugin):
877-
"""Tests that fetchart.art_for_album respects the scale & filesize
878-
configurations (e.g., minwidth, enforce_ratio, max_filesize)
879-
"""
883+
def fs_source_get(_self, album, settings, paths):
884+
if paths:
885+
yield fetchart.Candidate(
886+
logger, source_name=_self.ID, path=cls.IMAGE_PATH
887+
)
880888

881-
IMG_225x225 = os.path.join(_common.RSRC, b"abbey.jpg")
882-
IMG_348x348 = os.path.join(_common.RSRC, b"abbey-different.jpg")
889+
patch("beetsplug.fetchart.FileSystem.get", fs_source_get).start()
890+
cls.addClassCleanup(patch.stopall)
883891

884-
IMG_225x225_SIZE = os.stat(util.syspath(IMG_225x225)).st_size
892+
def get_album_art(self):
893+
return self.plugin.art_for_album(_common.Bag(), [""], True)
885894

886-
RESIZE_OP = "resize"
887-
DEINTERLACE_OP = "deinterlace"
888-
REFORMAT_OP = "reformat"
889895

890-
album = _common.Bag()
896+
class AlbumArtOperationConfigurationTest(AlbumArtOperationTestCase):
897+
"""Check that scale & filesize configuration is respected.
891898
892-
def get_album_art(self):
893-
return self.plugin.art_for_album(self.album, [""], True)
894-
895-
def _assert_image_operated(self, image_file, operation, should_operate):
896-
self.image_file = image_file
897-
with patch.object(
898-
ArtResizer.shared, operation, return_value=self.image_file
899-
) as mock_operation:
900-
self.get_album_art()
901-
assert mock_operation.called == should_operate
902-
903-
def _require_backend(self):
904-
"""Skip the test if the art resizer doesn't have ImageMagick or
905-
PIL (so comparisons and measurements are unavailable).
906-
"""
907-
if not ArtResizer.shared.local:
908-
self.skipTest("ArtResizer has no local imaging backend available")
899+
Depending on `minwidth`, `enforce_ratio`, `margin_px`, and `margin_percent`
900+
configuration the plugin should or should not return an art candidate.
901+
"""
909902

910-
def test_respect_minwidth(self):
911-
self._require_backend()
912-
self.plugin.minwidth = 300
903+
def test_minwidth(self):
904+
self.plugin.minwidth = self.IMAGE_WIDTH / 2
913905
assert self.get_album_art()
914906

915-
def test_respect_minwidth_no(self):
916-
self._require_backend()
917-
self.plugin.minwidth = 600
907+
self.plugin.minwidth = self.IMAGE_WIDTH * 2
918908
assert not self.get_album_art()
919909

920-
def test_respect_enforce_ratio_yes(self):
921-
self._require_backend()
910+
def test_enforce_ratio(self):
922911
self.plugin.enforce_ratio = True
923912
assert not self.get_album_art()
924913

925-
def test_respect_enforce_ratio_no(self):
926914
self.plugin.enforce_ratio = False
927915
assert self.get_album_art()
928916

929-
def test_respect_enforce_ratio_px_above(self):
930-
self._require_backend()
917+
def test_enforce_ratio_with_px_margin(self):
931918
self.plugin.enforce_ratio = True
932-
self.plugin.margin_px = 5
919+
920+
self.plugin.margin_px = self.IMAGE_WIDTH_HEIGHT_DIFF * 0.5
933921
assert not self.get_album_art()
934922

935-
def test_respect_enforce_ratio_px_below(self):
936-
self._require_backend()
937-
self.plugin.enforce_ratio = True
938-
self.plugin.margin_px = 15
923+
self.plugin.margin_px = self.IMAGE_WIDTH_HEIGHT_DIFF * 1.5
939924
assert self.get_album_art()
940925

941-
def test_respect_enforce_ratio_percent_above(self):
942-
self._require_backend()
926+
def test_enforce_ratio_with_percent_margin(self):
943927
self.plugin.enforce_ratio = True
944-
self.plugin.margin_percent = (500 - 490) / 500 * 0.5
928+
diff_by_width = self.IMAGE_WIDTH_HEIGHT_DIFF / self.IMAGE_WIDTH
929+
930+
self.plugin.margin_percent = diff_by_width * 0.5
945931
assert not self.get_album_art()
946932

947-
def test_respect_enforce_ratio_percent_below(self):
948-
self._require_backend()
949-
self.plugin.enforce_ratio = True
950-
self.plugin.margin_percent = (500 - 490) / 500 * 1.5
933+
self.plugin.margin_percent = diff_by_width * 1.5
951934
assert self.get_album_art()
952935

953-
def test_resize_if_necessary(self):
954-
self._require_backend()
955-
self.plugin.maxwidth = 300
936+
937+
class AlbumArtPerformOperationTest(AlbumArtOperationTestCase):
938+
"""Test that the art is resized and deinterlaced if necessary."""
939+
940+
def setUp(self):
941+
super().setUp()
942+
self.resizer_mock = patch.object(
943+
ArtResizer.shared, "resize", return_value=self.IMAGE_PATH
944+
).start()
945+
self.deinterlacer_mock = patch.object(
946+
ArtResizer.shared, "deinterlace", return_value=self.IMAGE_PATH
947+
).start()
948+
949+
def test_resize(self):
950+
self.plugin.maxwidth = self.IMAGE_WIDTH / 2
956951
assert self.get_album_art()
957-
self._assert_image_operated(IMAGE_PATH, self.RESIZE_OP, True)
952+
assert self.resizer_mock.called
958953

959-
def test_fileresize(self):
960-
self._require_backend()
961-
self.plugin.max_filesize = self.IMG_225x225_SIZE // 2
962-
self._assert_image_operated(self.IMG_225x225, self.RESIZE_OP, True)
954+
def test_file_resized(self):
955+
self.plugin.max_filesize = self.IMAGE_FILESIZE // 2
956+
assert self.get_album_art()
957+
assert self.resizer_mock.called
963958

964-
def test_fileresize_if_necessary(self):
965-
self._require_backend()
966-
self.plugin.max_filesize = IMAGE_SIZE
967-
self._assert_image_operated(IMAGE_PATH, self.RESIZE_OP, False)
959+
def test_file_not_resized(self):
960+
self.plugin.max_filesize = self.IMAGE_FILESIZE
968961
assert self.get_album_art()
962+
assert not self.resizer_mock.called
969963

970-
def test_fileresize_no_scale(self):
971-
self._require_backend()
972-
self.plugin.maxwidth = 300
973-
self.plugin.max_filesize = self.IMG_225x225_SIZE // 2
974-
self._assert_image_operated(self.IMG_225x225, self.RESIZE_OP, True)
964+
def test_file_resized_but_not_scaled(self):
965+
self.plugin.maxwidth = self.IMAGE_WIDTH * 2
966+
self.plugin.max_filesize = self.IMAGE_FILESIZE // 2
967+
assert self.get_album_art()
968+
assert self.resizer_mock.called
975969

976-
def test_fileresize_and_scale(self):
977-
self._require_backend()
978-
self.plugin.maxwidth = 200
979-
self.plugin.max_filesize = self.IMG_225x225_SIZE // 2
980-
self._assert_image_operated(self.IMG_225x225, self.RESIZE_OP, True)
970+
def test_file_resized_and_scaled(self):
971+
self.plugin.maxwidth = self.IMAGE_WIDTH / 2
972+
self.plugin.max_filesize = self.IMAGE_FILESIZE // 2
973+
assert self.get_album_art()
974+
assert self.resizer_mock.called
981975

982-
def test_deinterlace(self):
983-
self._require_backend()
976+
def test_deinterlaced(self):
984977
self.plugin.deinterlace = True
985-
self._assert_image_operated(self.IMG_225x225, self.DEINTERLACE_OP, True)
978+
assert self.get_album_art()
979+
assert self.deinterlacer_mock.called
980+
981+
def test_not_deinterlaced(self):
986982
self.plugin.deinterlace = False
987-
self._assert_image_operated(
988-
self.IMG_225x225, self.DEINTERLACE_OP, False
989-
)
983+
assert self.get_album_art()
984+
assert not self.deinterlacer_mock.called
990985

991-
def test_deinterlace_and_resize(self):
992-
self._require_backend()
993-
self.plugin.maxwidth = 300
986+
def test_deinterlaced_and_resized(self):
987+
self.plugin.maxwidth = self.IMAGE_WIDTH / 2
994988
self.plugin.deinterlace = True
995-
self._assert_image_operated(self.IMG_348x348, self.DEINTERLACE_OP, True)
996-
self._assert_image_operated(self.IMG_348x348, self.RESIZE_OP, True)
989+
assert self.get_album_art()
990+
assert self.deinterlacer_mock.called
991+
assert self.resizer_mock.called
997992

998993

999994
class DeprecatedConfigTest(unittest.TestCase):

0 commit comments

Comments
 (0)