From d7df41afa2c8205435d53df2ea5941018a342a8a Mon Sep 17 00:00:00 2001 From: George <41969151+geo-martino@users.noreply.github.com> Date: Mon, 1 Apr 2024 17:48:30 -0400 Subject: [PATCH] switch _in_range `Comparer` method to be inclusive (#56) * switch _in_range ItemComparer method to be inclusive * switch assertions on manual playlist check * update release history * update release history again --- docs/release-history.rst | 2 ++ musify/file/base.py | 2 +- musify/processors/compare.py | 2 +- .../libraries/local/playlist/test_xautopf.py | 31 +++++++++++-------- 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/docs/release-history.rst b/docs/release-history.rst index f7754900..b4dfaca9 100644 --- a/docs/release-history.rst +++ b/docs/release-history.rst @@ -60,6 +60,8 @@ Changed all MusifyItem types that may have their URI property set manually. * :py:class:`.ItemSorter` now shuffles randomly on unsupported types + prioritises fields settings over shuffle settings +* :py:meth:`.Comparer._in_range` now uses inclusive range i.e. ``a <= x <= b`` where ``x`` is the value to compare + and ``a`` and ``b`` are the limits. Previously used exclusive range i.e. ``a < x < b`` Fixed ----- diff --git a/musify/file/base.py b/musify/file/base.py index 1f74cdc9..70f0124b 100644 --- a/musify/file/base.py +++ b/musify/file/base.py @@ -73,7 +73,7 @@ def _validate_existence(path: str): @classmethod def get_filepaths(cls, folder: str) -> set[str]: """Get all files in a given folder that match this File object's valid filetypes recursively.""" - paths = set() + paths: set[str] = set() for ext in cls.valid_extensions: paths |= set(glob(join(folder, "**", f"*{ext}"), recursive=True, include_hidden=True)) diff --git a/musify/processors/compare.py b/musify/processors/compare.py index 257290b9..31f1f163 100644 --- a/musify/processors/compare.py +++ b/musify/processors/compare.py @@ -268,7 +268,7 @@ def _is_not_in(self, value: Any | None, expected: Sequence[Any] | None) -> bool: @dynamicprocessormethod def _in_range(self, value: Any | None, expected: Sequence[Any] | None) -> bool: - return expected[0] < value < expected[1] if value is not None and expected[0] is not None else False + return expected[0] <= value <= expected[1] if value is not None and expected[0] is not None else False @dynamicprocessormethod def _not_in_range(self, value: Any | None, expected: Sequence[Any] | None) -> bool: diff --git a/tests/libraries/local/playlist/test_xautopf.py b/tests/libraries/local/playlist/test_xautopf.py index f46765f2..f3243a45 100644 --- a/tests/libraries/local/playlist/test_xautopf.py +++ b/tests/libraries/local/playlist/test_xautopf.py @@ -10,8 +10,8 @@ from musify.file.exception import InvalidFileType from musify.file.path_mapper import PathMapper, PathStemMapper -from musify.libraries.local.library import MusicBee -from musify.libraries.local.playlist import XAutoPF, load_playlist +from musify.libraries.local.library import MusicBee, LocalLibrary +from musify.libraries.local.playlist import XAutoPF from musify.libraries.local.track import LocalTrack from tests.libraries.local.playlist.testers import LocalPlaylistTester from tests.libraries.local.track.utils import random_track, random_tracks @@ -176,31 +176,36 @@ def test_save_playlist(self, tracks: list[LocalTrack], path: str, path_mapper: P assert path.startswith("../") +@pytest.mark.manual +@pytest.fixture(scope="module") +def library() -> LocalLibrary: + mapper = PathStemMapper({"../..": os.getenv("TEST_PL_LIBRARY", "")}) + library = MusicBee(musicbee_folder=join(os.getenv("TEST_PL_LIBRARY"), "MusicBee"), path_mapper=mapper) + library.load_tracks() + return library + + # noinspection PyTestUnpassedFixture, SpellCheckingInspection @pytest.mark.manual @pytest.mark.skipif( "not config.getoption('-m') and not config.getoption('-k')", reason="Only runs when the test or marker is specified explicitly by the user", ) -@pytest.mark.parametrize("source,expected,mapper", [ +@pytest.mark.parametrize("source,expected", [ ( join(os.getenv("TEST_PL_SOURCE", ""), f"{splitext(basename(name))[0]}.xautopf"), join(os.getenv("TEST_PL_COMPARISON", ""), f"{splitext(basename(name))[0]}.m3u"), - PathStemMapper({"../..": os.getenv("TEST_PL_LIBRARY", "")}) ) for name in glob(join(os.getenv("TEST_PL_SOURCE", ""), "**", "*.xautopf"), recursive=True) ]) -def test_playlist_paths_manual(source: str, expected: str, mapper: PathMapper): +def test_playlist_paths_manual(library: LocalLibrary, source: str, expected: str): assert exists(source) assert exists(expected) - library = MusicBee(musicbee_folder=join(os.getenv("TEST_PL_LIBRARY"), "MusicBee"), path_mapper=mapper) - library.load_tracks() - - pl = load_playlist(source, tracks=library.tracks, path_mapper=mapper) - paths_source = [track.path for track in pl] + pl = library.load_playlist(source) - with open(expected, "r") as f: - paths_expected = [mapper.map(line.strip()) for line in f] + with open(expected, "r", encoding="utf-8") as f: + paths_expected = [library.path_mapper.map(line.strip()) for line in f] - assert paths_source == paths_expected + assert sorted(track.path for track in pl) == sorted(paths_expected) + assert [track.path for track in pl] == paths_expected