Dedupe TestHelper and _common.TestCase setup

This commit is contained in:
Šarūnas Nejus 2024-07-13 17:32:18 +01:00
parent 2566e22744
commit 3e278159ed
No known key found for this signature in database
GPG key ID: DD28F6704DBE3435
30 changed files with 197 additions and 207 deletions

View file

@ -15,7 +15,6 @@
"""Some common functionality for beets' test cases."""
import os
import shutil
import sys
import tempfile
import unittest
@ -185,70 +184,6 @@ class Assertions:
)
# A test harness for all beets tests.
# Provides temporary, isolated configuration.
class TestCase(unittest.TestCase, Assertions):
"""A unittest.TestCase subclass that saves and restores beets'
global configuration. This allows tests to make temporary
modifications that will then be automatically removed when the test
completes. Also provides some additional assertion methods, a
temporary directory, and a DummyIO.
"""
def setUp(self):
# A "clean" source list including only the defaults.
beets.config.sources = []
beets.config.read(user=False, defaults=True)
# Direct paths to a temporary directory. Tests can also use this
# temporary directory.
self.temp_dir = util.bytestring_path(tempfile.mkdtemp())
beets.config["statefile"] = os.fsdecode(
os.path.join(self.temp_dir, b"state.pickle")
)
beets.config["library"] = os.fsdecode(
os.path.join(self.temp_dir, b"library.db")
)
beets.config["directory"] = os.fsdecode(
os.path.join(self.temp_dir, b"libdir")
)
# Set $HOME, which is used by Confuse to create directories.
self._old_home = os.environ.get("HOME")
os.environ["HOME"] = os.fsdecode(self.temp_dir)
# Initialize, but don't install, a DummyIO.
self.io = DummyIO()
def tearDown(self):
if os.path.isdir(syspath(self.temp_dir)):
shutil.rmtree(syspath(self.temp_dir))
if self._old_home is None:
del os.environ["HOME"]
else:
os.environ["HOME"] = self._old_home
self.io.restore()
beets.config.clear()
beets.config._materialized = False
class LibTestCase(TestCase):
"""A test case that includes an in-memory library object (`lib`) and
an item added to the library (`i`).
"""
def setUp(self):
super().setUp()
self.lib = beets.library.Library(":memory:")
self.i = item(self.lib)
def tearDown(self):
self.lib._connection().close()
super().tearDown()
# Mock I/O.

View file

@ -36,11 +36,13 @@ import os.path
import shutil
import subprocess
import sys
import unittest
from contextlib import contextmanager
from enum import Enum
from io import StringIO
from tempfile import mkdtemp, mkstemp
from typing import ClassVar
from unittest.mock import patch
import responses
from mediafile import Image, MediaFile
@ -174,11 +176,19 @@ class TestHelper(_common.Assertions):
Make sure you call ``teardown_beets()`` afterwards.
"""
self.create_temp_dir()
os.environ["BEETSDIR"] = os.fsdecode(self.temp_dir)
temp_dir_str = os.fsdecode(self.temp_dir)
self.env_patcher = patch.dict(
"os.environ",
{
"BEETSDIR": temp_dir_str,
"HOME": temp_dir_str, # used by Confuse to create directories.
},
)
self.env_patcher.start()
self.config = beets.config
self.config.clear()
self.config.read()
self.config.sources = []
self.config.read(user=False, defaults=True)
self.config["plugins"] = []
self.config["verbose"] = 1
@ -195,13 +205,16 @@ class TestHelper(_common.Assertions):
dbpath = ":memory:"
self.lib = Library(dbpath, self.libdir)
# Initialize, but don't install, a DummyIO.
self.io = _common.DummyIO()
def teardown_beets(self):
self.env_patcher.stop()
self.io.restore()
self.lib._close()
if "BEETSDIR" in os.environ:
del os.environ["BEETSDIR"]
self.remove_temp_dir()
self.config.clear()
beets.config.read(user=False, defaults=True)
beets.config.clear()
beets.config._materialized = False
def load_plugins(self, *plugins):
"""Load and initialize plugins by names.
@ -490,6 +503,38 @@ class TestHelper(_common.Assertions):
return path
# A test harness for all beets tests.
# Provides temporary, isolated configuration.
class BeetsTestCase(unittest.TestCase, TestHelper):
"""A unittest.TestCase subclass that saves and restores beets'
global configuration. This allows tests to make temporary
modifications that will then be automatically removed when the test
completes. Also provides some additional assertion methods, a
temporary directory, and a DummyIO.
"""
def setUp(self):
self.setup_beets()
def tearDown(self):
self.teardown_beets()
class LibTestCase(BeetsTestCase):
"""A test case that includes an in-memory library object (`lib`) and
an item added to the library (`i`).
"""
def setUp(self):
super().setUp()
self.lib = beets.library.Library(":memory:")
self.i = _common.item(self.lib)
def tearDown(self):
self.lib._connection().close()
super().tearDown()
class ImportHelper(TestHelper):
"""Provides tools to setup a library, a directory containing files that are
to be imported and an import session. The class also provides stubs for the

View file

@ -26,7 +26,12 @@ import responses
from beets import config, importer, library, logging, util
from beets.autotag import AlbumInfo, AlbumMatch
from beets.test import _common
from beets.test.helper import CleanupModulesMixin, FetchImageHelper, capture_log
from beets.test.helper import (
BeetsTestCase,
CleanupModulesMixin,
FetchImageHelper,
capture_log,
)
from beets.util import syspath
from beets.util.artresizer import ArtResizer
from beetsplug import fetchart
@ -44,7 +49,7 @@ class Settings:
setattr(self, k, v)
class UseThePlugin(CleanupModulesMixin, _common.TestCase):
class UseThePlugin(CleanupModulesMixin, BeetsTestCase):
modules = (fetchart.__name__, ArtResizer.__module__)
def setUp(self):
@ -977,14 +982,14 @@ class ArtForAlbumTest(UseThePlugin):
self._assert_image_operated(self.IMG_348x348, self.RESIZE_OP, True)
class DeprecatedConfigTest(_common.TestCase):
class DeprecatedConfigTest(BeetsTestCase):
"""While refactoring the plugin, the remote_priority option was deprecated,
and a new codepath should translate its effect. Check that it actually does
so.
"""
# If we subclassed UseThePlugin, the configuration change would either be
# overwritten by _common.TestCase or be set after constructing the
# overwritten by BeetsTestCase or be set after constructing the
# plugin object
def setUp(self):
super().setUp()
@ -995,7 +1000,7 @@ class DeprecatedConfigTest(_common.TestCase):
self.assertEqual(type(self.plugin.sources[-1]), fetchart.FileSystem)
class EnforceRatioConfigTest(_common.TestCase):
class EnforceRatioConfigTest(BeetsTestCase):
"""Throw some data at the regexes."""
def _load_with_config(self, values, should_raise):

View file

@ -20,11 +20,11 @@ from datetime import timedelta
from beets import library
from beets.test import _common
from beets.test.helper import TestHelper
from beets.test.helper import BeetsTestCase
from beetsplug import beatport
class BeatportTest(_common.TestCase, TestHelper):
class BeatportTest(BeetsTestCase):
def _make_release_response(self):
"""Returns a dict that mimics a response from the beatport API.
@ -601,7 +601,7 @@ class BeatportTest(_common.TestCase, TestHelper):
self.assertEqual(track.genre, test_track.genre)
class BeatportResponseEmptyTest(_common.TestCase, TestHelper):
class BeatportResponseEmptyTest(BeetsTestCase):
def _make_tracks_response(self):
results = [
{

View file

@ -22,8 +22,8 @@ import unittest
from mediafile import MediaFile
from beets import util
from beets.test import _common, helper
from beets.test.helper import capture_log, control_stdin
from beets.test import _common
from beets.test.helper import BeetsTestCase, capture_log, control_stdin
from beets.util import bytestring_path, displayable_path
@ -33,7 +33,7 @@ def shell_quote(text):
return shlex.quote(text)
class TestHelper(helper.TestHelper):
class ConvertMixin:
def tagged_copy_cmd(self, tag):
"""Return a conversion command that copies files and appends
`tag` to the copy.
@ -84,8 +84,12 @@ class TestHelper(helper.TestHelper):
)
class ConvertTestCase(BeetsTestCase, ConvertMixin):
pass
@_common.slow_test()
class ImportConvertTest(_common.TestCase, TestHelper):
class ImportConvertTest(ConvertTestCase):
def setUp(self):
self.setup_beets(disk=True) # Converter is threaded
self.importer = self.create_importer()
@ -163,7 +167,7 @@ class ConvertCommand:
@_common.slow_test()
class ConvertCliTest(_common.TestCase, TestHelper, ConvertCommand):
class ConvertCliTest(ConvertTestCase, ConvertCommand):
def setUp(self):
self.setup_beets(disk=True) # Converter is threaded
self.album = self.add_album_fixture(ext="ogg")
@ -310,7 +314,7 @@ class ConvertCliTest(_common.TestCase, TestHelper, ConvertCommand):
@_common.slow_test()
class NeverConvertLossyFilesTest(_common.TestCase, TestHelper, ConvertCommand):
class NeverConvertLossyFilesTest(ConvertTestCase, ConvertCommand):
"""Test the effect of the `never_convert_lossy_files` option."""
def setUp(self):

View file

@ -18,14 +18,13 @@
import unittest
from beets import config
from beets.test import _common
from beets.test._common import Bag
from beets.test.helper import capture_log
from beets.test.helper import BeetsTestCase, capture_log
from beets.util.id_extractors import extract_discogs_id_regex
from beetsplug.discogs import DiscogsPlugin
class DGAlbumInfoTest(_common.TestCase):
class DGAlbumInfoTest(BeetsTestCase):
def _make_release(self, tracks=None):
"""Returns a Bag that mimics a discogs_client.Release. The list
of elements on the returned Bag is incomplete, including just

View file

@ -47,7 +47,6 @@ class EmbedartCliTest(TestHelper, FetchImageHelper):
abbey_differentpath = os.path.join(_common.RSRC, b"abbey-different.jpg")
def setUp(self):
self.io = _common.DummyIO()
self.io.install()
self.setup_beets() # Converter is threaded
self.load_plugins("embedart")

View file

@ -19,8 +19,7 @@ import tempfile
import unittest
from beets import config, plugins
from beets.test import _common
from beets.test.helper import TestHelper, capture_log
from beets.test.helper import BeetsTestCase, capture_log
def get_temporary_path():
@ -30,7 +29,7 @@ def get_temporary_path():
return os.path.join(temporary_directory, temporary_name)
class HookTest(_common.TestCase, TestHelper):
class HookTest(BeetsTestCase):
TEST_HOOK_COUNT = 5
def setUp(self):

View file

@ -24,6 +24,7 @@ import mediafile
from beets.library import Item
from beets.plugins import BeetsPlugin
from beets.test import _common
from beets.test.helper import BeetsTestCase
from beets.util import bytestring_path, syspath
field_extension = mediafile.MediaField(
@ -41,7 +42,7 @@ list_field_extension = mediafile.ListMediaField(
)
class ExtendedFieldTestMixin(_common.TestCase):
class ExtendedFieldTestMixin(BeetsTestCase):
def _mediafile_fixture(self, name, extension="mp3"):
name = bytestring_path(name + "." + extension)
src = os.path.join(_common.RSRC, name)

View file

@ -23,14 +23,13 @@ from beets import config
from beets.dbcore import OrQuery
from beets.dbcore.query import FixedFieldSort, MultipleSort, NullSort
from beets.library import Album, Item, parse_query_string
from beets.test import _common
from beets.test.helper import TestHelper
from beets.test.helper import BeetsTestCase
from beets.ui import UserError
from beets.util import CHAR_REPLACE, bytestring_path, syspath
from beetsplug.smartplaylist import SmartPlaylistPlugin
class SmartPlaylistTest(_common.TestCase):
class SmartPlaylistTest(BeetsTestCase):
def test_build_queries(self):
spl = SmartPlaylistPlugin()
self.assertIsNone(spl._matched_playlists)
@ -339,7 +338,7 @@ class SmartPlaylistTest(_common.TestCase):
self.assertEqual(content, b"http://beets:8337/item/3/file\n")
class SmartPlaylistCLITest(_common.TestCase, TestHelper):
class SmartPlaylistCLITest(BeetsTestCase):
def setUp(self):
self.setup_beets()

View file

@ -9,7 +9,7 @@ import responses
from beets import config
from beets.library import Item
from beets.test import _common
from beets.test.helper import TestHelper
from beets.test.helper import BeetsTestCase
from beetsplug import spotify
@ -25,7 +25,7 @@ def _params(url):
return parse_qs(urlparse(url).query)
class SpotifyPluginTest(_common.TestCase, TestHelper):
class SpotifyPluginTest(BeetsTestCase):
@responses.activate
def setUp(self):
config.clear()

View file

@ -6,8 +6,7 @@ from urllib.parse import parse_qs, urlparse
import responses
from beets import config
from beets.test import _common
from beets.test.helper import TestHelper
from beets.test.helper import BeetsTestCase
from beetsplug import subsonicupdate
@ -26,7 +25,7 @@ def _params(url):
return parse_qs(urlparse(url).query)
class SubsonicPluginTest(_common.TestCase, TestHelper):
class SubsonicPluginTest(BeetsTestCase):
"""Test class for subsonicupdate."""
@responses.activate

View file

@ -3,11 +3,11 @@
import unittest
from beets import config
from beets.test import _common
from beets.test.helper import BeetsTestCase
from beetsplug.the import FORMAT, PATTERN_A, PATTERN_THE, ThePlugin
class ThePluginTest(_common.TestCase):
class ThePluginTest(BeetsTestCase):
def test_unthe_with_default_patterns(self):
self.assertEqual(ThePlugin().unthe("", PATTERN_THE), "")
self.assertEqual(

View file

@ -9,10 +9,11 @@ import unittest
from beets import logging
from beets.library import Album, Item
from beets.test import _common
from beets.test.helper import LibTestCase
from beetsplug import web
class WebPluginTest(_common.LibTestCase):
class WebPluginTest(LibTestCase):
def setUp(self):
super().setUp()
self.log = logging.getLogger("beets.web")

View file

@ -20,7 +20,7 @@ import unittest
from unittest.mock import patch
from beets.test import _common
from beets.test.helper import CleanupModulesMixin, TestHelper
from beets.test.helper import BeetsTestCase, CleanupModulesMixin
from beets.util import command_output, syspath
from beets.util.artresizer import IMBackend, PILBackend
@ -48,7 +48,7 @@ class DummyPILBackend(PILBackend):
pass
class ArtResizerFileSizeTest(CleanupModulesMixin, _common.TestCase, TestHelper):
class ArtResizerFileSizeTest(CleanupModulesMixin, BeetsTestCase):
"""Unittest test case for Art Resizer to a specific filesize."""
modules = (IMBackend.__module__,)

View file

@ -22,11 +22,11 @@ from beets import autotag, config
from beets.autotag import AlbumInfo, TrackInfo, match
from beets.autotag.hooks import Distance, string_dist
from beets.library import Item
from beets.test import _common
from beets.test.helper import BeetsTestCase
from beets.util import plurality
class PluralityTest(_common.TestCase):
class PluralityTest(BeetsTestCase):
def test_plurality_consensus(self):
objs = [1, 1, 1, 1]
obj, freq = plurality(objs)
@ -146,7 +146,7 @@ def _clear_weights():
Distance.__dict__["_weights"].cache = {}
class DistanceTest(_common.TestCase):
class DistanceTest(BeetsTestCase):
def tearDown(self):
super().tearDown()
_clear_weights()
@ -330,7 +330,7 @@ class DistanceTest(_common.TestCase):
)
class TrackDistanceTest(_common.TestCase):
class TrackDistanceTest(BeetsTestCase):
def test_identical_tracks(self):
item = _make_item("one", 1)
info = _make_trackinfo()[0]
@ -358,7 +358,7 @@ class TrackDistanceTest(_common.TestCase):
self.assertEqual(dist, 0.0)
class AlbumDistanceTest(_common.TestCase):
class AlbumDistanceTest(BeetsTestCase):
def _mapping(self, items, info):
out = {}
for i, t in zip(items, info.tracks):
@ -664,7 +664,7 @@ class ApplyTestUtil:
autotag.apply_metadata(info, mapping)
class ApplyTest(_common.TestCase, ApplyTestUtil):
class ApplyTest(BeetsTestCase, ApplyTestUtil):
def setUp(self):
super().setUp()
@ -925,7 +925,7 @@ class ApplyTest(_common.TestCase, ApplyTestUtil):
self.assertEqual(self.items[0].data_source, "MusicBrainz")
class ApplyCompilationTest(_common.TestCase, ApplyTestUtil):
class ApplyCompilationTest(BeetsTestCase, ApplyTestUtil):
def setUp(self):
super().setUp()
@ -1073,7 +1073,7 @@ class StringDistanceTest(unittest.TestCase):
self.assertEqual(dist, 0.0)
class EnumTest(_common.TestCase):
class EnumTest(BeetsTestCase):
"""
Test Enum Subclasses defined in beets.util.enumeration
"""

View file

@ -25,7 +25,7 @@ from beets.dbcore.query import (
InvalidQueryArgumentValueError,
_parse_periods,
)
from beets.test import _common
from beets.test.helper import LibTestCase
def _date(string):
@ -152,7 +152,7 @@ def _parsetime(s):
return time.mktime(datetime.strptime(s, "%Y-%m-%d %H:%M").timetuple())
class DateQueryTest(_common.LibTestCase):
class DateQueryTest(LibTestCase):
def setUp(self):
super().setUp()
self.i.added = _parsetime("2013-03-30 22:21")
@ -187,7 +187,7 @@ class DateQueryTest(_common.LibTestCase):
self.assertEqual(len(matched), 0)
class DateQueryTestRelative(_common.LibTestCase):
class DateQueryTestRelative(LibTestCase):
def setUp(self):
super().setUp()
@ -233,7 +233,7 @@ class DateQueryTestRelative(_common.LibTestCase):
self.assertEqual(len(matched), 0)
class DateQueryTestRelativeMore(_common.LibTestCase):
class DateQueryTestRelativeMore(LibTestCase):
def setUp(self):
super().setUp()
self.i.added = _parsetime(datetime.now().strftime("%Y-%m-%d %H:%M"))

View file

@ -25,10 +25,11 @@ import beets.library
from beets import util
from beets.test import _common
from beets.test._common import item, touch
from beets.test.helper import BeetsTestCase
from beets.util import MoveOperation, bytestring_path, syspath
class MoveTest(_common.TestCase):
class MoveTest(BeetsTestCase):
def setUp(self):
super().setUp()
@ -207,7 +208,7 @@ class MoveTest(_common.TestCase):
self.assertEqual(self.i.path, util.normpath(self.dest))
class HelperTest(_common.TestCase):
class HelperTest(BeetsTestCase):
def test_ancestry_works_on_file(self):
p = "/a/b/c"
a = ["/", "/a", "/a/b"]
@ -244,7 +245,7 @@ class HelperTest(_common.TestCase):
self.assertEqual(util.path_as_posix(p), a)
class AlbumFileTest(_common.TestCase):
class AlbumFileTest(BeetsTestCase):
def setUp(self):
super().setUp()
@ -311,7 +312,7 @@ class AlbumFileTest(_common.TestCase):
self.assertIn(b"testotherdir", self.i.path)
class ArtFileTest(_common.TestCase):
class ArtFileTest(BeetsTestCase):
def setUp(self):
super().setUp()
@ -485,7 +486,7 @@ class ArtFileTest(_common.TestCase):
self.assertExists(oldartpath)
class RemoveTest(_common.TestCase):
class RemoveTest(BeetsTestCase):
def setUp(self):
super().setUp()
@ -546,7 +547,7 @@ class RemoveTest(_common.TestCase):
# Tests that we can "delete" nonexistent files.
class SoftRemoveTest(_common.TestCase):
class SoftRemoveTest(BeetsTestCase):
def setUp(self):
super().setUp()
@ -564,7 +565,7 @@ class SoftRemoveTest(_common.TestCase):
self.fail("OSError when removing path")
class SafeMoveCopyTest(_common.TestCase):
class SafeMoveCopyTest(BeetsTestCase):
def setUp(self):
super().setUp()
@ -612,7 +613,7 @@ class SafeMoveCopyTest(_common.TestCase):
self.assertExists(self.path)
class PruneTest(_common.TestCase):
class PruneTest(BeetsTestCase):
def setUp(self):
super().setUp()
@ -632,7 +633,7 @@ class PruneTest(_common.TestCase):
self.assertNotExists(self.sub)
class WalkTest(_common.TestCase):
class WalkTest(BeetsTestCase):
def setUp(self):
super().setUp()
@ -666,7 +667,7 @@ class WalkTest(_common.TestCase):
self.assertEqual(res[0], (self.base, [], []))
class UniquePathTest(_common.TestCase):
class UniquePathTest(BeetsTestCase):
def setUp(self):
super().setUp()
@ -694,7 +695,7 @@ class UniquePathTest(_common.TestCase):
self.assertEqual(path, os.path.join(self.base, b"x.3.mp3"))
class MkDirAllTest(_common.TestCase):
class MkDirAllTest(BeetsTestCase):
def test_parent_exists(self):
path = os.path.join(self.temp_dir, b"foo", b"bar", b"baz", b"qux.mp3")
util.mkdirall(path)

View file

@ -36,6 +36,7 @@ from beets.importer import albums_in_dir
from beets.test import _common
from beets.test.helper import (
AutotagStub,
BeetsTestCase,
ImportHelper,
TestHelper,
capture_log,
@ -44,7 +45,7 @@ from beets.test.helper import (
from beets.util import bytestring_path, displayable_path, syspath
class ScrubbedImportTest(_common.TestCase, ImportHelper):
class ScrubbedImportTest(BeetsTestCase, ImportHelper):
def setUp(self):
self.setup_beets(disk=True)
self.load_plugins("scrub")
@ -99,7 +100,7 @@ class ScrubbedImportTest(_common.TestCase, ImportHelper):
@_common.slow_test()
class NonAutotaggedImportTest(_common.TestCase, ImportHelper):
class NonAutotaggedImportTest(BeetsTestCase, ImportHelper):
def setUp(self):
self.setup_beets(disk=True)
self._create_import_dir(2)
@ -344,7 +345,7 @@ class ImportPasswordRarTest(ImportZipTest):
return os.path.join(_common.RSRC, b"password.rar")
class ImportSingletonTest(_common.TestCase, ImportHelper):
class ImportSingletonTest(BeetsTestCase, ImportHelper):
"""Test ``APPLY`` and ``ASIS`` choices for an import session with
singletons config set to True.
"""
@ -467,7 +468,7 @@ class ImportSingletonTest(_common.TestCase, ImportHelper):
self.assertEqual(item.title, "Applied Title 1 - formatted")
class ImportTest(_common.TestCase, ImportHelper):
class ImportTest(BeetsTestCase, ImportHelper):
"""Test APPLY, ASIS and SKIP choices."""
def setUp(self):
@ -681,7 +682,7 @@ class ImportTest(_common.TestCase, ImportHelper):
)
class ImportTracksTest(_common.TestCase, ImportHelper):
class ImportTracksTest(BeetsTestCase, ImportHelper):
"""Test TRACKS and APPLY choice."""
def setUp(self):
@ -715,7 +716,7 @@ class ImportTracksTest(_common.TestCase, ImportHelper):
self.assert_file_in_lib(b"singletons", b"Applied Title 1.mp3")
class ImportCompilationTest(_common.TestCase, ImportHelper):
class ImportCompilationTest(BeetsTestCase, ImportHelper):
"""Test ASIS import of a folder containing tracks with different artists."""
def setUp(self):
@ -834,7 +835,7 @@ class ImportCompilationTest(_common.TestCase, ImportHelper):
self.assertTrue(asserted_multi_artists_0 and asserted_multi_artists_1)
class ImportExistingTest(_common.TestCase, ImportHelper):
class ImportExistingTest(BeetsTestCase, ImportHelper):
"""Test importing files that are already in the library directory."""
def setUp(self):
@ -959,7 +960,7 @@ class ImportExistingTest(_common.TestCase, ImportHelper):
self.assertNotExists(self.import_media[0].path)
class GroupAlbumsImportTest(_common.TestCase, ImportHelper):
class GroupAlbumsImportTest(BeetsTestCase, ImportHelper):
def setUp(self):
self.setup_beets()
self._create_import_dir(3)
@ -1031,7 +1032,7 @@ class GlobalGroupAlbumsImportTest(GroupAlbumsImportTest):
config["import"]["group_albums"] = True
class ChooseCandidateTest(_common.TestCase, ImportHelper):
class ChooseCandidateTest(BeetsTestCase, ImportHelper):
def setUp(self):
self.setup_beets()
self._create_import_dir(1)
@ -1054,7 +1055,7 @@ class ChooseCandidateTest(_common.TestCase, ImportHelper):
self.assertEqual(self.lib.albums().get().album, "Applied Album MM")
class InferAlbumDataTest(_common.TestCase):
class InferAlbumDataTest(BeetsTestCase):
def setUp(self):
super().setUp()
@ -1365,7 +1366,7 @@ class ImportDuplicateSingletonTest(unittest.TestCase, TestHelper):
return item
class TagLogTest(_common.TestCase):
class TagLogTest(BeetsTestCase):
def test_tag_log_line(self):
sio = StringIO()
handler = logging.StreamHandler(sio)
@ -1484,7 +1485,7 @@ def _mkmp3(path):
)
class AlbumsInDirTest(_common.TestCase):
class AlbumsInDirTest(BeetsTestCase):
def setUp(self):
super().setUp()
@ -1526,7 +1527,7 @@ class AlbumsInDirTest(_common.TestCase):
self.assertEqual(len(album), 1)
class MultiDiscAlbumsInDirTest(_common.TestCase):
class MultiDiscAlbumsInDirTest(BeetsTestCase):
def create_music(self, files=True, ascii=True):
"""Create some music in multiple album directories.
@ -1751,7 +1752,7 @@ class ReimportTest(unittest.TestCase, ImportHelper):
self.assertEqual(self._album().data_source, "match_source")
class ImportPretendTest(_common.TestCase, ImportHelper):
class ImportPretendTest(BeetsTestCase, ImportHelper):
"""Test the pretend commandline option"""
def __init__(self, method_name="runTest"):
@ -1944,7 +1945,7 @@ def mocked_get_recording_by_id(
"musicbrainzngs.get_release_by_id",
Mock(side_effect=mocked_get_release_by_id),
)
class ImportMusicBrainzIdTest(_common.TestCase, ImportHelper):
class ImportMusicBrainzIdTest(BeetsTestCase, ImportHelper):
"""Test the --musicbrainzid argument."""
MB_RELEASE_PREFIX = "https://musicbrainz.org/release/"

View file

@ -32,14 +32,14 @@ import beets.library
from beets import config, plugins, util
from beets.test import _common
from beets.test._common import item
from beets.test.helper import TestHelper
from beets.test.helper import BeetsTestCase, LibTestCase, TestHelper
from beets.util import bytestring_path, syspath
# Shortcut to path normalization.
np = util.normpath
class LoadTest(_common.LibTestCase):
class LoadTest(LibTestCase):
def test_load_restores_data_from_db(self):
original_title = self.i.title
self.i.title = "something"
@ -53,7 +53,7 @@ class LoadTest(_common.LibTestCase):
self.assertNotIn("artist", self.i._dirty)
class StoreTest(_common.LibTestCase):
class StoreTest(LibTestCase):
def test_store_changes_database_value(self):
self.i.year = 1987
self.i.store()
@ -94,7 +94,7 @@ class StoreTest(_common.LibTestCase):
self.assertNotIn("flex1", album.items()[0])
class AddTest(_common.TestCase):
class AddTest(BeetsTestCase):
def setUp(self):
super().setUp()
self.lib = beets.library.Library(":memory:")
@ -126,14 +126,14 @@ class AddTest(_common.TestCase):
self.assertEqual(new_grouping, self.i.grouping)
class RemoveTest(_common.LibTestCase):
class RemoveTest(LibTestCase):
def test_remove_deletes_from_db(self):
self.i.remove()
c = self.lib._connection().execute("select * from items")
self.assertIsNone(c.fetchone())
class GetSetTest(_common.TestCase):
class GetSetTest(BeetsTestCase):
def setUp(self):
super().setUp()
self.i = item()
@ -169,7 +169,7 @@ class GetSetTest(_common.TestCase):
self.assertIsNone(i.get("flexx"))
class DestinationTest(_common.TestCase):
class DestinationTest(BeetsTestCase):
def setUp(self):
super().setUp()
# default directory is ~/Music and the only reason why it was switched
@ -182,10 +182,6 @@ class DestinationTest(_common.TestCase):
super().tearDown()
self.lib._connection().close()
# Reset config if it was changed in test cases
config.clear()
config.read(user=False, defaults=True)
def test_directory_works_with_trailing_slash(self):
self.lib.directory = b"one/"
self.lib.path_formats = [("default", "two")]
@ -551,7 +547,7 @@ class DestinationTest(_common.TestCase):
self.assertEqual(self.i.destination(), np("one/foo/two"))
class ItemFormattedMappingTest(_common.LibTestCase):
class ItemFormattedMappingTest(LibTestCase):
def test_formatted_item_value(self):
formatted = self.i.formatted()
self.assertEqual(formatted["artist"], "the artist")
@ -624,7 +620,7 @@ class PathFormattingMixin:
self.assertEqual(actual, dest)
class DestinationFunctionTest(_common.TestCase, PathFormattingMixin):
class DestinationFunctionTest(BeetsTestCase, PathFormattingMixin):
def setUp(self):
super().setUp()
self.lib = beets.library.Library(":memory:")
@ -733,7 +729,7 @@ class DestinationFunctionTest(_common.TestCase, PathFormattingMixin):
self._assert_dest(b"/base/Alice & Bob")
class DisambiguationTest(_common.TestCase, PathFormattingMixin):
class DisambiguationTest(BeetsTestCase, PathFormattingMixin):
def setUp(self):
super().setUp()
self.lib = beets.library.Library(":memory:")
@ -822,7 +818,7 @@ class DisambiguationTest(_common.TestCase, PathFormattingMixin):
self._assert_dest(b"/base/foo/the title", self.i1)
class SingletonDisambiguationTest(_common.TestCase, PathFormattingMixin):
class SingletonDisambiguationTest(BeetsTestCase, PathFormattingMixin):
def setUp(self):
super().setUp()
self.lib = beets.library.Library(":memory:")
@ -907,7 +903,7 @@ class SingletonDisambiguationTest(_common.TestCase, PathFormattingMixin):
self._assert_dest(b"/base/foo/the title", self.i1)
class PluginDestinationTest(_common.TestCase):
class PluginDestinationTest(BeetsTestCase):
def setUp(self):
super().setUp()
@ -959,7 +955,7 @@ class PluginDestinationTest(_common.TestCase):
self._assert_dest(b"the artist bar_baz")
class AlbumInfoTest(_common.TestCase):
class AlbumInfoTest(BeetsTestCase):
def setUp(self):
super().setUp()
self.lib = beets.library.Library(":memory:")
@ -1064,7 +1060,7 @@ class AlbumInfoTest(_common.TestCase):
self.assertEqual(i.album, ai.album)
class ArtDestinationTest(_common.TestCase):
class ArtDestinationTest(BeetsTestCase):
def setUp(self):
super().setUp()
config["art_filename"] = "artimage"
@ -1092,7 +1088,7 @@ class ArtDestinationTest(_common.TestCase):
self.assertIn(b"artYimage", art)
class PathStringTest(_common.TestCase):
class PathStringTest(BeetsTestCase):
def setUp(self):
super().setUp()
self.lib = beets.library.Library(":memory:")
@ -1178,7 +1174,7 @@ class PathStringTest(_common.TestCase):
self.assertTrue(isinstance(alb.artpath, bytes))
class MtimeTest(_common.TestCase):
class MtimeTest(BeetsTestCase):
def setUp(self):
super().setUp()
self.ipath = os.path.join(self.temp_dir, b"testfile.mp3")
@ -1216,7 +1212,7 @@ class MtimeTest(_common.TestCase):
self.assertGreaterEqual(self.i.mtime, self._mtime())
class ImportTimeTest(_common.TestCase):
class ImportTimeTest(BeetsTestCase):
def setUp(self):
super().setUp()
self.lib = beets.library.Library(":memory:")
@ -1232,7 +1228,7 @@ class ImportTimeTest(_common.TestCase):
self.assertGreater(self.singleton.added, 0)
class TemplateTest(_common.LibTestCase):
class TemplateTest(LibTestCase):
def test_year_formatted_in_template(self):
self.i.year = 123
self.i.store()
@ -1262,7 +1258,7 @@ class TemplateTest(_common.LibTestCase):
self.assertEqual(f"{item:$tagada}", "togodo")
class UnicodePathTest(_common.LibTestCase):
class UnicodePathTest(LibTestCase):
def test_unicode_path(self):
self.i.path = os.path.join(_common.RSRC, "unicode\u2019d.mp3".encode())
# If there are any problems with unicode paths, we will raise

View file

@ -10,10 +10,10 @@ import beets.logging as blog
import beetsplug
from beets import plugins, ui
from beets.test import _common, helper
from beets.test._common import TestCase
from beets.test.helper import BeetsTestCase
class LoggingTest(TestCase):
class LoggingTest(BeetsTestCase):
def test_logging_management(self):
l1 = log.getLogger("foo123")
l2 = blog.getLogger("foo123")
@ -162,7 +162,7 @@ class LoggingLevelTest(unittest.TestCase, helper.TestHelper):
@_common.slow_test()
class ConcurrentEventsTest(TestCase, helper.TestHelper):
class ConcurrentEventsTest(BeetsTestCase):
"""Similar to LoggingLevelTest but lower-level and focused on multiple
events interaction. Since this is a bit heavy we don't do it in
LoggingLevelTest.

View file

@ -20,10 +20,10 @@ from unittest import mock
from beets import config
from beets.autotag import mb
from beets.test import _common
from beets.test.helper import BeetsTestCase
class MBAlbumInfoTest(_common.TestCase):
class MBAlbumInfoTest(BeetsTestCase):
def _make_release(
self,
date_str="2009",
@ -662,7 +662,7 @@ class MBAlbumInfoTest(_common.TestCase):
self.assertEqual(t[1].trackdisambig, "SECOND TRACK")
class ParseIDTest(_common.TestCase):
class ParseIDTest(BeetsTestCase):
def test_parse_id_correct(self):
id_string = "28e32c71-1450-463e-92bf-e0a46446fc11"
out = mb._parse_id(id_string)
@ -680,7 +680,7 @@ class ParseIDTest(_common.TestCase):
self.assertEqual(out, id_string)
class ArtistFlatteningTest(_common.TestCase):
class ArtistFlatteningTest(BeetsTestCase):
def _credit_dict(self, suffix=""):
return {
"artist": {

View file

@ -21,7 +21,7 @@ from datetime import datetime
from beets.library import Item
from beets.test import _common
from beets.test.helper import TestHelper
from beets.test.helper import BeetsTestCase
def _parsetime(s):
@ -32,7 +32,7 @@ def _is_windows():
return platform.system() == "Windows"
class MetaSyncTest(_common.TestCase, TestHelper):
class MetaSyncTest(BeetsTestCase):
itunes_library_unix = os.path.join(_common.RSRC, b"itunes_library_unix.xml")
itunes_library_windows = os.path.join(
_common.RSRC, b"itunes_library_windows.xml"

View file

@ -31,6 +31,7 @@ from beets.dbcore.query import (
)
from beets.library import Item, Library
from beets.test import _common, helper
from beets.test.helper import BeetsTestCase, LibTestCase
from beets.util import syspath
# Because the absolute path begins with something like C:, we
@ -48,7 +49,7 @@ class TestHelper(helper.TestHelper):
self.assertNotIn(item.id, result_ids)
class AnyFieldQueryTest(_common.LibTestCase):
class AnyFieldQueryTest(LibTestCase):
def test_no_restriction(self):
q = dbcore.query.AnyFieldQuery(
"title",
@ -92,7 +93,7 @@ class AssertsMixin:
# A test case class providing a library with some dummy data and some
# assertions involving that data.
class DummyDataTestCase(_common.TestCase, AssertsMixin):
class DummyDataTestCase(BeetsTestCase, AssertsMixin):
def setUp(self):
super().setUp()
self.lib = beets.library.Library(":memory:")
@ -418,7 +419,7 @@ class GetTest(DummyDataTestCase):
self.assertIsInstance(raised.exception, ParsingError)
class MatchTest(_common.TestCase):
class MatchTest(BeetsTestCase):
def setUp(self):
super().setUp()
self.item = _common.item()
@ -487,7 +488,7 @@ class MatchTest(_common.TestCase):
self.assertNotEqual(q3, q4)
class PathQueryTest(_common.LibTestCase, TestHelper, AssertsMixin):
class PathQueryTest(LibTestCase, TestHelper, AssertsMixin):
def setUp(self):
super().setUp()
@ -871,7 +872,7 @@ class NoneQueryTest(unittest.TestCase, TestHelper):
self.assertInResult(item, matched)
class NotQueryMatchTest(_common.TestCase):
class NotQueryMatchTest(BeetsTestCase):
"""Test `query.NotQuery` matching against a single item, using the same
cases and assertions as on `MatchTest`, plus assertion on the negated
queries (ie. assertTrue(q) -> assertFalse(NotQuery(q))).
@ -1129,7 +1130,7 @@ class NotQueryTest(DummyDataTestCase):
pass
class RelatedQueriesTest(_common.TestCase, AssertsMixin):
class RelatedQueriesTest(BeetsTestCase, AssertsMixin):
"""Test album-level queries with track-level filters and vice-versa."""
def setUp(self):

View file

@ -20,11 +20,12 @@ import unittest
import beets.library
from beets import config, dbcore
from beets.test import _common
from beets.test.helper import BeetsTestCase
# A test case class providing a library with some dummy data and some
# assertions involving that data.
class DummyDataTestCase(_common.TestCase):
class DummyDataTestCase(BeetsTestCase):
def setUp(self):
super().setUp()
self.lib = beets.library.Library(":memory:")
@ -373,7 +374,7 @@ class ConfigSortTest(DummyDataTestCase):
self.assertGreater(results[0].albumartist, results[1].albumartist)
class CaseSensitivityTest(DummyDataTestCase, _common.TestCase):
class CaseSensitivityTest(DummyDataTestCase, BeetsTestCase):
"""If case_insensitive is false, lower-case values should be placed
after all upper-case values. E.g., `Foo Qux bar`
"""

View file

@ -31,6 +31,7 @@ from beets import autotag, config, library, plugins, ui, util
from beets.autotag.match import distance
from beets.test import _common
from beets.test.helper import (
BeetsTestCase,
TestHelper,
capture_stdout,
control_stdin,
@ -108,7 +109,7 @@ class ListTest(unittest.TestCase):
self.assertNotIn("the album", stdout.getvalue())
class RemoveTest(_common.TestCase, TestHelper):
class RemoveTest(BeetsTestCase):
def setUp(self):
super().setUp()
@ -454,7 +455,7 @@ class WriteTest(unittest.TestCase, TestHelper):
self.assertIn(f"{old_title} -> new title", output)
class MoveTest(_common.TestCase):
class MoveTest(BeetsTestCase):
def setUp(self):
super().setUp()
@ -562,7 +563,7 @@ class MoveTest(_common.TestCase):
self.assertNotExists(self.otherdir)
class UpdateTest(_common.TestCase):
class UpdateTest(BeetsTestCase):
def setUp(self):
super().setUp()
@ -763,7 +764,7 @@ class UpdateTest(_common.TestCase):
self.assertNotEqual(item.lyrics, "new lyrics")
class PrintTest(_common.TestCase):
class PrintTest(BeetsTestCase):
def setUp(self):
super().setUp()
self.io.install()
@ -802,7 +803,7 @@ class PrintTest(_common.TestCase):
del os.environ["LC_CTYPE"]
class ImportTest(_common.TestCase):
class ImportTest(BeetsTestCase):
def test_quiet_timid_disallowed(self):
config["import"]["quiet"] = True
config["import"]["timid"] = True
@ -1145,7 +1146,7 @@ class ConfigTest(unittest.TestCase, TestHelper):
)
class ShowModelChangeTest(_common.TestCase):
class ShowModelChangeTest(BeetsTestCase):
def setUp(self):
super().setUp()
self.io.install()
@ -1197,7 +1198,7 @@ class ShowModelChangeTest(_common.TestCase):
self.assertIn("bar", out)
class ShowChangeTest(_common.TestCase):
class ShowChangeTest(BeetsTestCase):
def setUp(self):
super().setUp()
self.io.install()
@ -1358,7 +1359,7 @@ class ShowChangeTest(_common.TestCase):
@patch("beets.library.Item.try_filesize", Mock(return_value=987))
class SummarizeItemsTest(_common.TestCase):
class SummarizeItemsTest(BeetsTestCase):
def setUp(self):
super().setUp()
item = library.Item()
@ -1395,7 +1396,7 @@ class SummarizeItemsTest(_common.TestCase):
self.assertEqual(summary, "3 items, G 2, F 1, 4kbps, 32:42, 2.9 KiB")
class PathFormatTest(_common.TestCase):
class PathFormatTest(BeetsTestCase):
def test_custom_paths_prepend(self):
default_formats = ui.get_path_formats()
@ -1408,7 +1409,7 @@ class PathFormatTest(_common.TestCase):
@_common.slow_test()
class PluginTest(_common.TestCase, TestHelper):
class PluginTest(BeetsTestCase):
def test_plugin_command_from_pluginpath(self):
config["pluginpath"] = [_common.PLUGINPATH]
config["plugins"] = ["test"]
@ -1416,7 +1417,7 @@ class PluginTest(_common.TestCase, TestHelper):
@_common.slow_test()
class CompletionTest(_common.TestCase, TestHelper):
class CompletionTest(BeetsTestCase):
def test_completion(self):
# Load plugin commands
config["pluginpath"] = [_common.PLUGINPATH]
@ -1652,7 +1653,7 @@ class CommonOptionsParserTest(unittest.TestCase, TestHelper):
)
class EncodingTest(_common.TestCase):
class EncodingTest(BeetsTestCase):
"""Tests for the `terminal_encoding` config option and our
`_in_encoding` and `_out_encoding` utility functions.
"""

View file

@ -22,11 +22,12 @@ import unittest
from beets import library, ui
from beets.test import _common
from beets.test.helper import BeetsTestCase, LibTestCase
from beets.ui import commands
from beets.util import syspath
class QueryTest(_common.TestCase):
class QueryTest(BeetsTestCase):
def setUp(self):
super().setUp()
@ -87,7 +88,7 @@ class QueryTest(_common.TestCase):
self.check_do_query(0, 2, album=True, also_items=False)
class FieldsTest(_common.LibTestCase):
class FieldsTest(LibTestCase):
def setUp(self):
super().setUp()

View file

@ -23,10 +23,10 @@ from random import random
from beets import config, ui
from beets.test import _common
from beets.test.helper import control_stdin
from beets.test.helper import BeetsTestCase, LibTestCase, control_stdin
class InputMethodsTest(_common.TestCase):
class InputMethodsTest(BeetsTestCase):
def setUp(self):
super().setUp()
self.io.install()
@ -90,7 +90,7 @@ class InputMethodsTest(_common.TestCase):
self.assertEqual(items, ["1", "3"])
class InitTest(_common.LibTestCase):
class InitTest(LibTestCase):
def setUp(self):
super().setUp()
@ -129,7 +129,7 @@ class InitTest(_common.LibTestCase):
self.assertEqual(h, ui.human_seconds(i))
class ParentalDirCreation(_common.TestCase):
class ParentalDirCreation(BeetsTestCase):
def test_create_yes(self):
non_exist_path = _common.os.fsdecode(
os.path.join(self.temp_dir, b"nonexist", str(random()).encode())

View file

@ -24,6 +24,7 @@ from unittest.mock import Mock, patch
from beets import util
from beets.test import _common
from beets.test.helper import BeetsTestCase
class UtilTest(unittest.TestCase):
@ -157,7 +158,7 @@ class UtilTest(unittest.TestCase):
pass
class PathConversionTest(_common.TestCase):
class PathConversionTest(BeetsTestCase):
def test_syspath_windows_format(self):
with _common.platform_windows():
path = os.path.join("a", "b", "c")
@ -200,7 +201,7 @@ class PathConversionTest(_common.TestCase):
self.assertEqual(outpath, "C:\\caf\xe9".encode())
class PathTruncationTest(_common.TestCase):
class PathTruncationTest(BeetsTestCase):
def test_truncate_bytestring(self):
with _common.platform_posix():
p = util.truncate_path(b"abcde/fgh", 4)

View file

@ -18,9 +18,10 @@ import unittest
from beets import library, vfs
from beets.test import _common
from beets.test.helper import BeetsTestCase
class VFSTest(_common.TestCase):
class VFSTest(BeetsTestCase):
def setUp(self):
super().setUp()
self.lib = library.Library(