diff --git a/beets/test/helper.py b/beets/test/helper.py index 3132026c6..6f8607516 100644 --- a/beets/test/helper.py +++ b/beets/test/helper.py @@ -624,6 +624,17 @@ class ImportHelper(TestHelper): self.assertEqual(len(os.listdir(syspath(self.libdir))), 0) +class AsIsImporterMixin: + def setUp(self): + super().setUp() + self.prepare_album_for_import(1) + + def run_asis_importer(self, **kwargs): + importer = self.setup_importer(autotag=False, **kwargs) + importer.run() + return importer + + class ImportTestCase(ImportHelper, BeetsTestCase): pass diff --git a/test/plugins/test_convert.py b/test/plugins/test_convert.py index eca953c43..a60cb531a 100644 --- a/test/plugins/test_convert.py +++ b/test/plugins/test_convert.py @@ -24,6 +24,7 @@ from mediafile import MediaFile from beets import util from beets.test import _common from beets.test.helper import ( + AsIsImporterMixin, ImportHelper, PluginTestCase, capture_log, @@ -95,12 +96,9 @@ class ConvertTestCase(ConvertMixin, PluginTestCase): @_common.slow_test() -class ImportConvertTest(ImportHelper, ConvertTestCase): +class ImportConvertTest(AsIsImporterMixin, ImportHelper, ConvertTestCase): def setUp(self): super().setUp() - self.prepare_album_for_import(1) - self.importer = self.setup_importer(autotag=False) - self.config["convert"] = { "dest": os.path.join(self.temp_dir, b"convert"), "command": self.tagged_copy_cmd("convert"), @@ -111,7 +109,7 @@ class ImportConvertTest(ImportHelper, ConvertTestCase): } def test_import_converted(self): - self.importer.run() + self.run_asis_importer() item = self.lib.items().get() self.assertFileTag(item.path, "convert") @@ -120,7 +118,7 @@ class ImportConvertTest(ImportHelper, ConvertTestCase): def test_import_original_on_convert_error(self): # `false` exits with non-zero code self.config["convert"]["command"] = "false" - self.importer.run() + self.run_asis_importer() item = self.lib.items().get() self.assertIsNotNone(item) @@ -128,7 +126,7 @@ class ImportConvertTest(ImportHelper, ConvertTestCase): def test_delete_originals(self): self.config["convert"]["delete_originals"] = True - self.importer.run() + self.run_asis_importer() for path in self.importer.paths: for root, dirnames, filenames in os.walk(path): self.assertEqual( diff --git a/test/plugins/test_keyfinder.py b/test/plugins/test_keyfinder.py index 0517c7011..ae8243845 100644 --- a/test/plugins/test_keyfinder.py +++ b/test/plugins/test_keyfinder.py @@ -17,11 +17,11 @@ from unittest.mock import patch from beets import util from beets.library import Item -from beets.test.helper import ImportTestCase, PluginMixin +from beets.test.helper import AsIsImporterMixin, ImportTestCase, PluginMixin @patch("beets.util.command_output") -class KeyFinderTest(PluginMixin, ImportTestCase): +class KeyFinderTest(AsIsImporterMixin, PluginMixin, ImportTestCase): plugin = "keyfinder" def test_add_key(self, command_output): @@ -39,8 +39,7 @@ class KeyFinderTest(PluginMixin, ImportTestCase): def test_add_key_on_import(self, command_output): command_output.return_value = util.CommandOutput(b"dbm", b"") - self.prepare_album_for_import(1) - self.setup_importer(autotag=False).run() + self.run_asis_importer() item = self.lib.items().get() self.assertEqual(item["initial_key"], "C#m") diff --git a/test/plugins/test_permissions.py b/test/plugins/test_permissions.py index b28ee46d5..928dad568 100644 --- a/test/plugins/test_permissions.py +++ b/test/plugins/test_permissions.py @@ -6,7 +6,7 @@ import platform from unittest.mock import Mock, patch from beets.test._common import touch -from beets.test.helper import ImportTestCase, PluginMixin +from beets.test.helper import AsIsImporterMixin, ImportTestCase, PluginMixin from beets.util import displayable_path from beetsplug.permissions import ( check_permissions, @@ -15,14 +15,13 @@ from beetsplug.permissions import ( ) -class PermissionsPluginTest(PluginMixin, ImportTestCase): +class PermissionsPluginTest(AsIsImporterMixin, PluginMixin, ImportTestCase): plugin = "permissions" def setUp(self): super().setUp() self.config["permissions"] = {"file": "777", "dir": "777"} - self.prepare_album_for_import(1) def test_permissions_on_album_imported(self): self.do_thing(True) @@ -45,7 +44,6 @@ class PermissionsPluginTest(PluginMixin, ImportTestCase): & 0o777 ) - self.importer = self.setup_importer(autotag=False) typs = ["file", "dir"] track_file = (b"album", b"track_1.mp3") @@ -57,7 +55,7 @@ class PermissionsPluginTest(PluginMixin, ImportTestCase): False: {k: get_stat(v) for (k, v) in zip(typs, (track_file, ()))}, } - self.importer.run() + self.run_asis_importer() item = self.lib.items().get() self.assertPerms(item.path, "file", expect_success) @@ -94,7 +92,7 @@ class PermissionsPluginTest(PluginMixin, ImportTestCase): def do_set_art(self, expect_success): if platform.system() == "Windows": self.skipTest("permissions not available on Windows") - self.setup_importer(autotag=False).run() + self.run_asis_importer() album = self.lib.albums().get() artpath = os.path.join(self.temp_dir, b"cover.jpg") touch(artpath) diff --git a/test/plugins/test_replaygain.py b/test/plugins/test_replaygain.py index d0532caed..0e7b663f5 100644 --- a/test/plugins/test_replaygain.py +++ b/test/plugins/test_replaygain.py @@ -19,7 +19,7 @@ from typing import ClassVar from mediafile import MediaFile from beets import config -from beets.test.helper import ImportTestCase, has_program +from beets.test.helper import AsIsImporterMixin, ImportTestCase, has_program from beetsplug.replaygain import ( FatalGstreamerPluginReplayGainError, GStreamerBackend, @@ -68,9 +68,6 @@ class ReplayGainTestCase(ImportTestCase): except Exception: self.tearDown() - self.prepare_album_for_import(1) - self.importer = self.setup_importer(autotag=False) - def tearDown(self): self.unload_plugins() super().tearDown() @@ -360,9 +357,9 @@ class ReplayGainFfmpegNoiseCliTest( FNAME = "whitenoise" -class ImportTest: +class ImportTest(AsIsImporterMixin): def test_import_converted(self): - self.importer.run() + self.run_asis_importer() for item in self.lib.items(): # FIXME: Add fixtures with known track/album gain (within a # suitable tolerance) so that we can actually check correct diff --git a/test/test_importer.py b/test/test_importer.py index d0100688b..ab5eb6475 100644 --- a/test/test_importer.py +++ b/test/test_importer.py @@ -35,6 +35,7 @@ from beets.autotag import AlbumInfo, AlbumMatch, TrackInfo from beets.importer import albums_in_dir from beets.test import _common from beets.test.helper import ( + AsIsImporterMixin, AutotagStub, BeetsTestCase, ImportTestCase, @@ -45,15 +46,10 @@ from beets.test.helper import ( from beets.util import bytestring_path, displayable_path, syspath -class ScrubbedImportTest(PluginMixin, ImportTestCase): +class ScrubbedImportTest(AsIsImporterMixin, PluginMixin, ImportTestCase): db_on_disk = True plugin = "scrub" - def setUp(self): - super().setUp() - self.prepare_album_for_import(1) - self.setup_importer(autotag=False) - def test_tags_not_scrubbed(self): config["plugins"] = ["scrub"] config["scrub"]["auto"] = False @@ -61,7 +57,7 @@ class ScrubbedImportTest(PluginMixin, ImportTestCase): for mediafile in self.import_media: self.assertEqual(mediafile.artist, "Tag Artist") self.assertEqual(mediafile.album, "Tag Album") - self.importer.run() + self.run_asis_importer() for item in self.lib.items(): imported_file = os.path.join(item.path) imported_file = MediaFile(imported_file) @@ -75,7 +71,7 @@ class ScrubbedImportTest(PluginMixin, ImportTestCase): for mediafile in self.import_media: self.assertEqual(mediafile.artist, "Tag Artist") self.assertEqual(mediafile.album, "Tag Album") - self.importer.run() + self.run_asis_importer() for item in self.lib.items(): imported_file = os.path.join(item.path) imported_file = MediaFile(imported_file) @@ -89,7 +85,7 @@ class ScrubbedImportTest(PluginMixin, ImportTestCase): for mediafile in self.import_media: self.assertEqual(mediafile.artist, "Tag Artist") self.assertEqual(mediafile.album, "Tag Album") - self.importer.run() + self.run_asis_importer() for item in self.lib.items(): imported_file = os.path.join(item.path) imported_file = MediaFile(imported_file) @@ -98,22 +94,17 @@ class ScrubbedImportTest(PluginMixin, ImportTestCase): @_common.slow_test() -class NonAutotaggedImportTest(ImportTestCase): +class NonAutotaggedImportTest(AsIsImporterMixin, ImportTestCase): db_on_disk = True - def setUp(self): - super().setUp() - self.prepare_album_for_import(1) - self.setup_importer(autotag=False) - def test_album_created_with_track_artist(self): - self.importer.run() + self.run_asis_importer() albums = self.lib.albums() self.assertEqual(len(albums), 1) self.assertEqual(albums[0].albumartist, "Tag Artist") def test_import_copy_arrives(self): - self.importer.run() + self.run_asis_importer() for mediafile in self.import_media: self.assert_file_in_lib( b"Tag Artist", @@ -124,7 +115,7 @@ class NonAutotaggedImportTest(ImportTestCase): def test_threaded_import_copy_arrives(self): config["threaded"] = True - self.importer.run() + self.run_asis_importer() for mediafile in self.import_media: self.assert_file_in_lib( b"Tag Artist", @@ -133,35 +124,27 @@ class NonAutotaggedImportTest(ImportTestCase): ) def test_import_with_move_deletes_import_files(self): - config["import"]["move"] = True - for mediafile in self.import_media: self.assertExists(mediafile.path) - self.importer.run() + self.run_asis_importer(move=True) for mediafile in self.import_media: self.assertNotExists(mediafile.path) def test_import_with_move_prunes_directory_empty(self): - config["import"]["move"] = True - self.assertExists(os.path.join(self.import_dir, b"album")) - self.importer.run() + self.run_asis_importer(move=True) self.assertNotExists(os.path.join(self.import_dir, b"album")) def test_import_with_move_prunes_with_extra_clutter(self): self.touch(os.path.join(self.import_dir, b"album", b"alog.log")) config["clutter"] = ["*.log"] - config["import"]["move"] = True self.assertExists(os.path.join(self.import_dir, b"album")) - self.importer.run() + self.run_asis_importer(move=True) self.assertNotExists(os.path.join(self.import_dir, b"album")) def test_threaded_import_move_arrives(self): - config["import"]["move"] = True - config["import"]["threaded"] = True - - self.importer.run() + self.run_asis_importer(move=True, threaded=True) for mediafile in self.import_media: self.assert_file_in_lib( b"Tag Artist", @@ -170,36 +153,28 @@ class NonAutotaggedImportTest(ImportTestCase): ) def test_threaded_import_move_deletes_import(self): - config["import"]["move"] = True - config["threaded"] = True - - self.importer.run() + self.run_asis_importer(move=True, threaded=True) for mediafile in self.import_media: self.assertNotExists(mediafile.path) def test_import_without_delete_retains_files(self): - config["import"]["delete"] = False - self.importer.run() + self.run_asis_importer(delete=False) for mediafile in self.import_media: self.assertExists(mediafile.path) def test_import_with_delete_removes_files(self): - config["import"]["delete"] = True - - self.importer.run() + self.run_asis_importer(delete=True) for mediafile in self.import_media: self.assertNotExists(mediafile.path) def test_import_with_delete_prunes_directory_empty(self): - config["import"]["delete"] = True self.assertExists(os.path.join(self.import_dir, b"album")) - self.importer.run() + self.run_asis_importer(delete=True) self.assertNotExists(os.path.join(self.import_dir, b"album")) @unittest.skipUnless(_common.HAVE_SYMLINK, "need symlinks") def test_import_link_arrives(self): - config["import"]["link"] = True - self.importer.run() + self.run_asis_importer(link=True) for mediafile in self.import_media: filename = os.path.join( self.libdir, @@ -216,8 +191,7 @@ class NonAutotaggedImportTest(ImportTestCase): @unittest.skipUnless(_common.HAVE_HARDLINK, "need hardlinks") def test_import_hardlink_arrives(self): - config["import"]["hardlink"] = True - self.importer.run() + self.run_asis_importer(hardlink=True) for mediafile in self.import_media: filename = os.path.join( self.libdir, @@ -237,8 +211,7 @@ class NonAutotaggedImportTest(ImportTestCase): def test_import_reflink_arrives(self): # Detecting reflinks is currently tricky due to various fs # implementations, we'll just check the file exists. - config["import"]["reflink"] = True - self.importer.run() + self.run_asis_importer(reflink=True) for mediafile in self.import_media: self.assert_file_in_lib( b"Tag Artist", @@ -248,8 +221,7 @@ class NonAutotaggedImportTest(ImportTestCase): def test_import_reflink_auto_arrives(self): # Should pass regardless of reflink support due to fallback. - config["import"]["reflink"] = "auto" - self.importer.run() + self.run_asis_importer(reflink="auto") for mediafile in self.import_media: self.assert_file_in_lib( b"Tag Artist", @@ -269,7 +241,7 @@ def create_archive(session): return path -class RmTempTest(ImportTestCase): +class RmTempTest(BeetsTestCase): """Tests that temporarily extracted archives are properly removed after usage. """ @@ -285,20 +257,18 @@ class RmTempTest(ImportTestCase): archive_task = importer.ArchiveImportTask(zip_path) archive_task.extract() tmp_path = archive_task.toppath - self.setup_importer(autotag=False, import_dir=tmp_path) self.assertExists(tmp_path) archive_task.finalize(self) self.assertNotExists(tmp_path) -class ImportZipTest(ImportTestCase): +class ImportZipTest(AsIsImporterMixin, ImportTestCase): def test_import_zip(self): zip_path = create_archive(self) self.assertEqual(len(self.lib.items()), 0) self.assertEqual(len(self.lib.albums()), 0) - self.setup_importer(autotag=False, import_dir=zip_path) - self.importer.run() + self.run_asis_importer(import_dir=zip_path) self.assertEqual(len(self.lib.items()), 1) self.assertEqual(len(self.lib.albums()), 1) @@ -1402,14 +1372,9 @@ class ResumeImportTest(ImportTestCase): self.assertIsNotNone(self.lib.items("title:'Track 1'").get()) -class IncrementalImportTest(ImportTestCase): - def setUp(self): - super().setUp() - self.prepare_album_for_import(1) - +class IncrementalImportTest(AsIsImporterMixin, ImportTestCase): def test_incremental_album(self): - importer = self.setup_importer(autotag=False, incremental=True) - importer.run() + importer = self.run_asis_importer(incremental=True) # Change album name so the original file would be imported again # if incremental was off. @@ -1421,10 +1386,7 @@ class IncrementalImportTest(ImportTestCase): self.assertEqual(len(self.lib.albums()), 2) def test_incremental_item(self): - importer = self.setup_importer( - autotag=False, incremental=True, singletons=True - ) - importer.run() + importer = self.run_asis_importer(incremental=True, singletons=True) # Change track name so the original file would be imported again # if incremental was off. @@ -1436,10 +1398,9 @@ class IncrementalImportTest(ImportTestCase): self.assertEqual(len(self.lib.items()), 2) def test_invalid_state_file(self): - importer = self.setup_importer(autotag=False, incremental=True) with open(self.config["statefile"].as_filename(), "wb") as f: f.write(b"000") - importer.run() + self.run_asis_importer(incremental=True) self.assertEqual(len(self.lib.albums()), 1) diff --git a/test/test_logging.py b/test/test_logging.py index 29579fdb2..0cd5b6818 100644 --- a/test/test_logging.py +++ b/test/test_logging.py @@ -9,7 +9,12 @@ import beets.logging as blog import beetsplug from beets import plugins, ui from beets.test import _common, helper -from beets.test.helper import BeetsTestCase, ImportTestCase, PluginMixin +from beets.test.helper import ( + AsIsImporterMixin, + BeetsTestCase, + ImportTestCase, + PluginMixin, +) class LoggingTest(BeetsTestCase): @@ -46,7 +51,7 @@ class LoggingTest(BeetsTestCase): self.assertTrue(stream.getvalue(), "foo oof baz") -class LoggingLevelTest(PluginMixin, ImportTestCase): +class LoggingLevelTest(AsIsImporterMixin, PluginMixin, ImportTestCase): plugin = "dummy" class DummyModule: @@ -135,8 +140,7 @@ class LoggingLevelTest(PluginMixin, ImportTestCase): def test_import_stage_level0(self): self.config["verbose"] = 0 with helper.capture_log() as logs: - self.prepare_album_for_import(1) - self.setup_importer(autotag=False).run() + self.run_asis_importer() self.assertIn("dummy: warning import_stage", logs) self.assertNotIn("dummy: info import_stage", logs) self.assertNotIn("dummy: debug import_stage", logs) @@ -144,8 +148,7 @@ class LoggingLevelTest(PluginMixin, ImportTestCase): def test_import_stage_level1(self): self.config["verbose"] = 1 with helper.capture_log() as logs: - self.prepare_album_for_import(1) - self.setup_importer(autotag=False).run() + self.run_asis_importer() self.assertIn("dummy: warning import_stage", logs) self.assertIn("dummy: info import_stage", logs) self.assertNotIn("dummy: debug import_stage", logs) @@ -153,15 +156,14 @@ class LoggingLevelTest(PluginMixin, ImportTestCase): def test_import_stage_level2(self): self.config["verbose"] = 2 with helper.capture_log() as logs: - self.prepare_album_for_import(1) - self.setup_importer(autotag=False).run() + self.run_asis_importer() self.assertIn("dummy: warning import_stage", logs) self.assertIn("dummy: info import_stage", logs) self.assertIn("dummy: debug import_stage", logs) @_common.slow_test() -class ConcurrentEventsTest(ImportTestCase): +class ConcurrentEventsTest(AsIsImporterMixin, ImportTestCase): """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. @@ -264,20 +266,17 @@ class ConcurrentEventsTest(ImportTestCase): blog.getLogger("beets").set_global_level(blog.WARNING) with helper.capture_log() as logs: - self.prepare_album_for_import(1) - self.setup_importer(autotag=False).run() + self.run_asis_importer() self.assertEqual(logs, []) blog.getLogger("beets").set_global_level(blog.INFO) with helper.capture_log() as logs: - self.prepare_album_for_import(1) - self.setup_importer(autotag=False).run() + self.run_asis_importer() for l in logs: self.assertIn("import", l) self.assertIn("album", l) blog.getLogger("beets").set_global_level(blog.DEBUG) with helper.capture_log() as logs: - self.prepare_album_for_import(1) - self.setup_importer(autotag=False).run() + self.run_asis_importer() self.assertIn("Sending event: database_change", logs)