Skip to content

Commit

Permalink
switch _in_range Comparer method to be inclusive (#56)
Browse files Browse the repository at this point in the history
* switch _in_range ItemComparer method to be inclusive

* switch assertions on manual playlist check

* update release history

* update release history again
  • Loading branch information
geo-martino authored Apr 1, 2024
1 parent 70e8e87 commit d7df41a
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 15 deletions.
2 changes: 2 additions & 0 deletions docs/release-history.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
-----
Expand Down
2 changes: 1 addition & 1 deletion musify/file/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
2 changes: 1 addition & 1 deletion musify/processors/compare.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
31 changes: 18 additions & 13 deletions tests/libraries/local/playlist/test_xautopf.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

0 comments on commit d7df41a

Please sign in to comment.