Skip to content

Commit

Permalink
Configure plugins using PluginMixin.configure_plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
snejus committed Jul 28, 2024
1 parent 199f307 commit edc820d
Show file tree
Hide file tree
Showing 6 changed files with 234 additions and 325 deletions.
15 changes: 14 additions & 1 deletion beets/test/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
from io import StringIO
from pathlib import Path
from tempfile import mkdtemp, mkstemp
from typing import ClassVar
from typing import Any, ClassVar
from unittest.mock import patch

import responses
Expand Down Expand Up @@ -498,6 +498,19 @@ def unload_plugins(self) -> None:
Item._queries = getattr(Item, "_original_queries", {})
Album._queries = getattr(Album, "_original_queries", {})

@contextmanager
def configure_plugin(self, config: list[Any] | dict[str, Any]):
if isinstance(config, list):
beets.config[self.plugin] = config
else:
for key, value in config.items():
beets.config[self.plugin][key] = value
self.load_plugins(self.plugin)

yield

self.unload_plugins()


class PluginTestCase(PluginMixin, BeetsTestCase):
pass
Expand Down
179 changes: 73 additions & 106 deletions test/plugins/test_advancedrewrite.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,139 +16,106 @@
"""


from beets.test.helper import BeetsTestCase, PluginMixin
from beets.test.helper import PluginTestCase
from beets.ui import UserError

PLUGIN_NAME = "advancedrewrite"


class AdvancedRewritePluginTest(PluginMixin, BeetsTestCase):
class AdvancedRewritePluginTest(PluginTestCase):
plugin = "advancedrewrite"
preload_plugin = False

def test_simple_rewrite_example(self):
self.config[PLUGIN_NAME] = [
{"artist ODD EYE CIRCLE": "이달의 소녀 오드아이써클"},
]
self.load_plugins(PLUGIN_NAME)

item = self.add_item(
title="Uncover",
artist="ODD EYE CIRCLE",
albumartist="ODD EYE CIRCLE",
album="Mix & Match",
)
with self.configure_plugin(
[{"artist ODD EYE CIRCLE": "이달의 소녀 오드아이써클"}]
):
item = self.add_item(
artist="ODD EYE CIRCLE",
albumartist="ODD EYE CIRCLE",
)

self.assertEqual(item.artist, "이달의 소녀 오드아이써클")
self.assertEqual(item.artist, "이달의 소녀 오드아이써클")

def test_advanced_rewrite_example(self):
self.config[PLUGIN_NAME] = [
{
"match": "mb_artistid:dec0f331-cb08-4c8e-9c9f-aeb1f0f6d88c year:..2022",
"replacements": {
"artist": "이달의 소녀 오드아이써클",
"artist_sort": "LOONA / ODD EYE CIRCLE",
with self.configure_plugin(
[
{
"match": "mb_artistid:dec0f331-cb08-4c8e-9c9f-aeb1f0f6d88c year:..2022", # noqa: E501
"replacements": {
"artist": "이달의 소녀 오드아이써클",
"artist_sort": "LOONA / ODD EYE CIRCLE",
},
},
},
]
self.load_plugins(PLUGIN_NAME)

item_a = self.add_item(
title="Uncover",
artist="ODD EYE CIRCLE",
albumartist="ODD EYE CIRCLE",
artist_sort="ODD EYE CIRCLE",
albumartist_sort="ODD EYE CIRCLE",
album="Mix & Match",
mb_artistid="dec0f331-cb08-4c8e-9c9f-aeb1f0f6d88c",
year=2017,
)
item_b = self.add_item(
title="Air Force One",
artist="ODD EYE CIRCLE",
albumartist="ODD EYE CIRCLE",
artist_sort="ODD EYE CIRCLE",
albumartist_sort="ODD EYE CIRCLE",
album="ODD EYE CIRCLE <Version Up>",
mb_artistid="dec0f331-cb08-4c8e-9c9f-aeb1f0f6d88c",
year=2023,
)

# Assert that all replacements were applied to item_a
self.assertEqual("이달의 소녀 오드아이써클", item_a.artist)
self.assertEqual("LOONA / ODD EYE CIRCLE", item_a.artist_sort)
self.assertEqual("LOONA / ODD EYE CIRCLE", item_a.albumartist_sort)

# Assert that no replacements were applied to item_b
self.assertEqual("ODD EYE CIRCLE", item_b.artist)
]
):
item_a = self.add_item(
artist="ODD EYE CIRCLE",
artist_sort="ODD EYE CIRCLE",
mb_artistid="dec0f331-cb08-4c8e-9c9f-aeb1f0f6d88c",
year=2017,
)
item_b = self.add_item(
artist="ODD EYE CIRCLE",
artist_sort="ODD EYE CIRCLE",
mb_artistid="dec0f331-cb08-4c8e-9c9f-aeb1f0f6d88c",
year=2023,
)

# Assert that all replacements were applied to item_a
self.assertEqual("이달의 소녀 오드아이써클", item_a.artist)
self.assertEqual("LOONA / ODD EYE CIRCLE", item_a.artist_sort)
self.assertEqual("LOONA / ODD EYE CIRCLE", item_a.albumartist_sort)

# Assert that no replacements were applied to item_b
self.assertEqual("ODD EYE CIRCLE", item_b.artist)

def test_advanced_rewrite_example_with_multi_valued_field(self):
self.config[PLUGIN_NAME] = [
{
"match": "artist:배유빈 feat. 김미현",
"replacements": {
"artists": ["유빈", "미미"],
with self.configure_plugin(
[
{
"match": "artist:배유빈 feat. 김미현",
"replacements": {"artists": ["유빈", "미미"]},
},
},
]
self.load_plugins(PLUGIN_NAME)

item = self.add_item(
artist="배유빈 feat. 김미현",
artists=["배유빈", "김미현"],
)
]
):
item = self.add_item(
artist="배유빈 feat. 김미현",
artists=["배유빈", "김미현"],
)

self.assertEqual(item.artists, ["유빈", "미미"])
self.assertEqual(item.artists, ["유빈", "미미"])

def test_fail_when_replacements_empty(self):
self.config[PLUGIN_NAME] = [
{
"match": "artist:A",
"replacements": {},
},
]
with self.assertRaises(
UserError,
msg="Advanced rewrites must have at least one replacement",
):
self.load_plugins(PLUGIN_NAME)
), self.configure_plugin([{"match": "artist:A", "replacements": {}}]):
pass

def test_fail_when_rewriting_single_valued_field_with_list(self):
self.config[PLUGIN_NAME] = [
{
"match": "artist:'A & B'",
"replacements": {
"artist": ["C", "D"],
},
},
]
with self.assertRaises(
UserError,
msg="Field artist is not a multi-valued field but a list was given: C, D",
), self.configure_plugin(
[
{
"match": "artist:'A & B'",
"replacements": {"artist": ["C", "D"]},
},
]
):
self.load_plugins(PLUGIN_NAME)
pass

def test_combined_rewrite_example(self):
self.config[PLUGIN_NAME] = [
{"artist A": "B"},
{
"match": "album:'C'",
"replacements": {
"artist": "D",
},
},
]
self.load_plugins(PLUGIN_NAME)

item = self.add_item(
artist="A",
albumartist="A",
)
self.assertEqual(item.artist, "B")

item = self.add_item(
artist="C",
albumartist="C",
album="C",
)
self.assertEqual(item.artist, "D")
with self.configure_plugin(
[
{"artist A": "B"},
{"match": "album:'C'", "replacements": {"artist": "D"}},
]
):
item = self.add_item(artist="A", albumartist="A")
self.assertEqual(item.artist, "B")

item = self.add_item(artist="C", albumartist="C", album="C")
self.assertEqual(item.artist, "D")
43 changes: 23 additions & 20 deletions test/plugins/test_filefilter.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

"""Tests for the `filefilter` plugin.
"""
from beets import config
from beets.test.helper import ImportTestCase, PluginMixin
from beets.util import bytestring_path

Expand Down Expand Up @@ -42,10 +41,9 @@ def prepare_tracks_for_import(self):
self.single_track,
}

def _run(self, expected_album_count, expected_paths):
self.load_plugins("filefilter")

self.importer.run()
def _run(self, config, expected_album_count, expected_paths):
with self.configure_plugin(config):
self.importer.run()

self.assertEqual(len(self.lib.albums()), expected_album_count)
self.assertEqual({i.path for i in self.lib.items()}, expected_paths)
Expand All @@ -58,24 +56,28 @@ def setUp(self):

def test_import_default(self):
"""The default configuration should import everything."""
self._run(3, self.all_tracks)
self._run({}, 3, self.all_tracks)

def test_import_nothing(self):
config["filefilter"]["path"] = "not_there"
self._run(0, set())
self._run({"path": "not_there"}, 0, set())

def test_global_config(self):
config["filefilter"]["path"] = ".*album.*"
self._run(2, {self.album_track, self.other_album_track})
self._run(
{"path": ".*album.*"},
2,
{self.album_track, self.other_album_track},
)

def test_album_config(self):
config["filefilter"]["album_path"] = ".*other_album.*"
self._run(1, {self.other_album_track})
self._run(
{"album_path": ".*other_album.*"},
1,
{self.other_album_track},
)

def test_singleton_config(self):
"""Check that singleton configuration is ignored for album import."""
config["filefilter"]["singleton_path"] = ".*other_album.*"
self._run(3, self.all_tracks)
self._run({"singleton_path": ".*other_album.*"}, 3, self.all_tracks)


class FileFilterPluginSingletonTest(FileFilterPluginMixin):
Expand All @@ -84,14 +86,15 @@ def setUp(self):
self.importer = self.setup_singleton_importer(autotag=False, copy=False)

def test_global_config(self):
config["filefilter"]["path"] = ".*album.*"
self._run(0, {self.album_track, self.other_album_track})
self._run(
{"path": ".*album.*"}, 0, {self.album_track, self.other_album_track}
)

def test_album_config(self):
"""Check that album configuration is ignored for singleton import."""
config["filefilter"]["album_path"] = ".*other_album.*"
self._run(0, self.all_tracks)
self._run({"album_path": ".*other_album.*"}, 0, self.all_tracks)

def test_singleton_config(self):
config["filefilter"]["singleton_path"] = ".*other_album.*"
self._run(0, {self.other_album_track})
self._run(
{"singleton_path": ".*other_album.*"}, 0, {self.other_album_track}
)
Loading

0 comments on commit edc820d

Please sign in to comment.