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 Dec 7, 2024
1 parent 43387d1 commit 16c7c97
Show file tree
Hide file tree
Showing 3 changed files with 170 additions and 194 deletions.
42 changes: 22 additions & 20 deletions beets/test/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,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 @@ -153,12 +153,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 @@ -184,8 +199,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 @@ -202,15 +215,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 @@ -229,8 +233,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 @@ -452,7 +454,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 @@ -473,7 +475,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 @@ -494,7 +496,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 @@ -504,7 +506,7 @@ def unload_plugins(self) -> None:

@contextmanager
def configure_plugin(self, config: Any):
beets.config[self.plugin].set(config)
self.config[self.plugin].set(config)
self.load_plugins(self.plugin)

yield
Expand Down Expand Up @@ -624,7 +626,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
8 changes: 8 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,16 @@ Unreleased
----------

New features:

Bug fixes:

* :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 developers' local lyrics configuration.
:bug:`5133`

For packagers:

Other changes:

2.2.0 (December 02, 2024)
Expand Down
Loading

0 comments on commit 16c7c97

Please sign in to comment.