Skip to content

Commit

Permalink
lyrics: isolate test configuration
Browse files Browse the repository at this point in the history
Create 'helpers.ConfigMixin' which sets up testing configuration.
This is helpful for tests (e.g. test_lyrics.py) that only need the
configuration and do not require temp dir.

(#5102) Refactor lyrics tests to fix the issue global beets config
issue.

Additionally, add 'integration_test' mark that can be used to mark tests
that should only run once a week.
  • Loading branch information
snejus committed Oct 12, 2024
1 parent 5e43a7e commit 0d04952
Show file tree
Hide file tree
Showing 3 changed files with 176 additions and 211 deletions.
44 changes: 23 additions & 21 deletions beets/test/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@

import beets
import beets.plugins
from beets import autotag, config, importer, logging, util
from beets import autotag, importer, logging, util
from beets.autotag.hooks import AlbumInfo, TrackInfo
from beets.importer import ImportSession
from beets.library import Album, Item, Library
Expand Down Expand Up @@ -156,12 +156,27 @@ def check_reflink_support(path: str) -> bool:
return reflink.supported_at(path)


class ConfigMixin:
@cached_property
def config(self) -> beets.IncludeLazyConfig:
"""Base beets configuration for tests."""
config = beets.config
config.sources = []
config.read(user=False, defaults=True)

config["plugins"] = []
config["verbose"] = 1
config["ui"]["color"] = False
config["threaded"] = False
return config


NEEDS_REFLINK = unittest.skipUnless(
check_reflink_support(gettempdir()), "no reflink support for libdir"
)


class TestHelper(_common.Assertions):
class TestHelper(_common.Assertions, ConfigMixin):
"""Helper mixin for high-level cli and plugin tests.
This mixin provides methods to isolate beets' global state provide
Expand All @@ -187,8 +202,6 @@ def setup_beets(self):
- ``libdir`` Path to a subfolder of ``temp_dir``, containing the
library's media files. Same as ``config['directory']``.
- ``config`` The global configuration used by beets.
- ``lib`` Library instance created with the settings from
``config``.
Expand All @@ -205,15 +218,6 @@ def setup_beets(self):
)
self.env_patcher.start()

self.config = beets.config
self.config.sources = []
self.config.read(user=False, defaults=True)

self.config["plugins"] = []
self.config["verbose"] = 1
self.config["ui"]["color"] = False
self.config["threaded"] = False

self.libdir = os.path.join(self.temp_dir, b"libdir")
os.mkdir(syspath(self.libdir))
self.config["directory"] = os.fsdecode(self.libdir)
Expand All @@ -232,8 +236,6 @@ def teardown_beets(self):
self.io.restore()
self.lib._close()
self.remove_temp_dir()
beets.config.clear()
beets.config._materialized = False

# Library fixtures methods

Expand Down Expand Up @@ -462,7 +464,7 @@ def setUp(self):
self.i = _common.item(self.lib)


class PluginMixin:
class PluginMixin(ConfigMixin):
plugin: ClassVar[str]
preload_plugin: ClassVar[bool] = True

Expand All @@ -483,7 +485,7 @@ def load_plugins(self, *plugins: str) -> None:
"""
# FIXME this should eventually be handled by a plugin manager
plugins = (self.plugin,) if hasattr(self, "plugin") else plugins
beets.config["plugins"] = plugins
self.config["plugins"] = plugins
beets.plugins.load_plugins(plugins)
beets.plugins.find_plugins()

Expand All @@ -504,7 +506,7 @@ def unload_plugins(self) -> None:
# FIXME this should eventually be handled by a plugin manager
for plugin_class in beets.plugins._instances:
plugin_class.listeners = None
beets.config["plugins"] = []
self.config["plugins"] = []
beets.plugins._classes = set()
beets.plugins._instances = {}
Item._types = getattr(Item, "_original_types", {})
Expand All @@ -515,10 +517,10 @@ def unload_plugins(self) -> None:
@contextmanager
def configure_plugin(self, config: list[Any] | dict[str, Any]):
if isinstance(config, list):
beets.config[self.plugin] = config
self.config[self.plugin] = config
else:
for key, value in config.items():
beets.config[self.plugin][key] = value
self.config[self.plugin][key] = value
self.load_plugins(self.plugin)

yield
Expand Down Expand Up @@ -638,7 +640,7 @@ def _get_import_session(self, import_dir: bytes) -> ImportSession:
def setup_importer(
self, import_dir: bytes | None = None, **kwargs
) -> ImportSession:
config["import"].set_args({**self.default_import_config, **kwargs})
self.config["import"].set_args({**self.default_import_config, **kwargs})
self.importer = self._get_import_session(import_dir or self.import_dir)
return self.importer

Expand Down
6 changes: 5 additions & 1 deletion docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,12 @@ Bug fixes:
issues in the future.
:bug:`5289`
* :doc:`plugins/discogs`: Fix the ``TypeError`` when there is no description.
* Remove single quotes from all SQL queries
* Use single quotes in all SQL queries.
:bug:`4709`
* :doc:`plugins/lyrics`: Rewrite lyrics tests using pytest to provide isolated
configuration for each test case. This fixes the issue where some tests
failed because they read developer's local lyrics configuration.
:bug:`5133`

For packagers:

Expand Down
Loading

0 comments on commit 0d04952

Please sign in to comment.