diff --git a/beets/test/_common.py b/beets/test/_common.py index 790ea9422b..50dbde43f6 100644 --- a/beets/test/_common.py +++ b/beets/test/_common.py @@ -152,36 +152,28 @@ class Assertions: """A mixin with additional unit test assertions.""" def assertExists(self, path): # noqa - self.assertTrue( - os.path.exists(syspath(path)), f"file does not exist: {path!r}" - ) + assert os.path.exists(syspath(path)), f"file does not exist: {path!r}" def assertNotExists(self, path): # noqa - self.assertFalse( - os.path.exists(syspath(path)), f"file exists: {path!r}" - ) + assert not os.path.exists(syspath(path)), f"file exists: {path!r}" def assertIsFile(self, path): # noqa self.assertExists(path) - self.assertTrue( - os.path.isfile(syspath(path)), - "path exists, but is not a regular file: {!r}".format(path), - ) + assert os.path.isfile( + syspath(path) + ), "path exists, but is not a regular file: {!r}".format(path) def assertIsDir(self, path): # noqa self.assertExists(path) - self.assertTrue( - os.path.isdir(syspath(path)), - "path exists, but is not a directory: {!r}".format(path), - ) + assert os.path.isdir( + syspath(path) + ), "path exists, but is not a directory: {!r}".format(path) def assert_equal_path(self, a, b): """Check that two paths are equal.""" - self.assertEqual( - util.normpath(a), - util.normpath(b), - f"paths are not equal: {a!r} and {b!r}", - ) + a_bytes, b_bytes = util.normpath(a), util.normpath(b) + + assert a_bytes == b_bytes, f"{a_bytes=} != {b_bytes=}" # Mock I/O. diff --git a/beets/test/helper.py b/beets/test/helper.py index e94bf86cd1..470498b505 100644 --- a/beets/test/helper.py +++ b/beets/test/helper.py @@ -644,7 +644,7 @@ def assert_file_not_in_lib(self, *segments): self.assertNotExists(os.path.join(self.libdir, *segments)) def assert_lib_dir_empty(self): - self.assertEqual(len(os.listdir(syspath(self.libdir))), 0) + assert not os.listdir(syspath(self.libdir)) class AsIsImporterMixin: diff --git a/test/plugins/test_acousticbrainz.py b/test/plugins/test_acousticbrainz.py index 0182e57079..77a04dafaf 100644 --- a/test/plugins/test_acousticbrainz.py +++ b/test/plugins/test_acousticbrainz.py @@ -30,9 +30,10 @@ def test_basic(self): data = {"key 1": "value 1", "key 2": "value 2"} scheme = {"key 1": "attribute 1", "key 2": "attribute 2"} mapping = set(ab._map_data_to_scheme(data, scheme)) - self.assertEqual( - mapping, {("attribute 1", "value 1"), ("attribute 2", "value 2")} - ) + assert mapping == { + ("attribute 1", "value 1"), + ("attribute 2", "value 2"), + } def test_recurse(self): ab = AcousticPlugin() @@ -51,21 +52,18 @@ def test_recurse(self): }, } mapping = set(ab._map_data_to_scheme(data, scheme)) - self.assertEqual( - mapping, - { - ("attribute 1", "value"), - ("attribute 2", "subvalue"), - ("attribute 3", "subsubvalue"), - }, - ) + assert mapping == { + ("attribute 1", "value"), + ("attribute 2", "subvalue"), + ("attribute 3", "subsubvalue"), + } def test_composite(self): ab = AcousticPlugin() data = {"key 1": "part 1", "key 2": "part 2"} scheme = {"key 1": ("attribute", 0), "key 2": ("attribute", 1)} mapping = set(ab._map_data_to_scheme(data, scheme)) - self.assertEqual(mapping, {("attribute", "part 1 part 2")}) + assert mapping == {("attribute", "part 1 part 2")} def test_realistic(self): ab = AcousticPlugin() @@ -98,4 +96,4 @@ def test_realistic(self): ("moods_mirex", "Cluster3"), ("timbre", "bright"), } - self.assertEqual(mapping, expected) + assert mapping == expected diff --git a/test/plugins/test_advancedrewrite.py b/test/plugins/test_advancedrewrite.py index 65dece2473..6f4f8a59b4 100644 --- a/test/plugins/test_advancedrewrite.py +++ b/test/plugins/test_advancedrewrite.py @@ -16,6 +16,8 @@ """ +import pytest + from beets.test.helper import PluginTestCase from beets.ui import UserError @@ -35,7 +37,7 @@ def test_simple_rewrite_example(self): albumartist="ODD EYE CIRCLE", ) - self.assertEqual(item.artist, "이달의 소녀 오드아이써클") + assert item.artist == "이달의 소녀 오드아이써클" def test_advanced_rewrite_example(self): with self.configure_plugin( @@ -63,12 +65,12 @@ def test_advanced_rewrite_example(self): ) # 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 "이달의 소녀 오드아이써클" == item_a.artist + assert "LOONA / ODD EYE CIRCLE" == item_a.artist_sort + assert "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) + assert "ODD EYE CIRCLE" == item_b.artist def test_advanced_rewrite_example_with_multi_valued_field(self): with self.configure_plugin( @@ -84,19 +86,19 @@ def test_advanced_rewrite_example_with_multi_valued_field(self): artists=["배유빈", "김미현"], ) - self.assertEqual(item.artists, ["유빈", "미미"]) + assert item.artists == ["유빈", "미미"] def test_fail_when_replacements_empty(self): - with self.assertRaises( + with pytest.raises( UserError, - msg="Advanced rewrites must have at least one replacement", + match="Advanced rewrites must have at least one replacement", ), self.configure_plugin([{"match": "artist:A", "replacements": {}}]): pass def test_fail_when_rewriting_single_valued_field_with_list(self): - with self.assertRaises( + with pytest.raises( UserError, - msg="Field artist is not a multi-valued field but a list was given: C, D", + match="Field artist is not a multi-valued field but a list was given: C, D", ), self.configure_plugin( [ { @@ -115,7 +117,7 @@ def test_combined_rewrite_example(self): ] ): item = self.add_item(artist="A", albumartist="A") - self.assertEqual(item.artist, "B") + assert item.artist == "B" item = self.add_item(artist="C", albumartist="C", album="C") - self.assertEqual(item.artist, "D") + assert item.artist == "D" diff --git a/test/plugins/test_albumtypes.py b/test/plugins/test_albumtypes.py index 3dd63e9de5..f03e948195 100644 --- a/test/plugins/test_albumtypes.py +++ b/test/plugins/test_albumtypes.py @@ -35,7 +35,7 @@ def test_renames_types(self): album = self._create_album(album_types=["ep", "remix"]) subject = AlbumTypesPlugin() result = subject._atypes(album) - self.assertEqual("(EP)(Remix)", result) + assert "(EP)(Remix)" == result return def test_returns_only_specified_types(self): @@ -46,7 +46,7 @@ def test_returns_only_specified_types(self): album = self._create_album(album_types=["ep", "remix", "soundtrack"]) subject = AlbumTypesPlugin() result = subject._atypes(album) - self.assertEqual("(EP)", result) + assert "(EP)" == result def test_respects_type_order(self): """Tests if the types are returned in the same order as config.""" @@ -56,7 +56,7 @@ def test_respects_type_order(self): album = self._create_album(album_types=["ep", "remix"]) subject = AlbumTypesPlugin() result = subject._atypes(album) - self.assertEqual("(Remix)(EP)", result) + assert "(Remix)(EP)" == result return def test_ignores_va(self): @@ -71,7 +71,7 @@ def test_ignores_va(self): ) subject = AlbumTypesPlugin() result = subject._atypes(album) - self.assertEqual("(OST)", result) + assert "(OST)" == result def test_respects_defaults(self): """Tests if the plugin uses the default values if config not given.""" @@ -88,7 +88,7 @@ def test_respects_defaults(self): ) subject = AlbumTypesPlugin() result = subject._atypes(album) - self.assertEqual("[EP][Single][OST][Live][Remix]", result) + assert "[EP][Single][OST][Live][Remix]" == result def _set_config( self, diff --git a/test/plugins/test_art.py b/test/plugins/test_art.py index ce86b257f4..20bbcdced6 100644 --- a/test/plugins/test_art.py +++ b/test/plugins/test_art.py @@ -20,6 +20,7 @@ from unittest.mock import patch import confuse +import pytest import responses from beets import config, importer, logging, util @@ -209,23 +210,23 @@ def setUp(self): def test_invalid_type_returns_none(self): self.mock_response(self.URL, "image/watercolour") self.source.fetch_image(self.candidate, self.settings) - self.assertIsNone(self.candidate.path) + assert self.candidate.path is None def test_jpeg_type_returns_path(self): self.mock_response(self.URL, "image/jpeg") self.source.fetch_image(self.candidate, self.settings) - self.assertIsNotNone(self.candidate.path) + assert self.candidate.path is not None def test_extension_set_by_content_type(self): self.mock_response(self.URL, "image/png") self.source.fetch_image(self.candidate, self.settings) - self.assertEqual(os.path.splitext(self.candidate.path)[1], b".png") + assert os.path.splitext(self.candidate.path)[1] == b".png" self.assertExists(self.candidate.path) def test_does_not_rely_on_server_content_type(self): self.mock_response(self.URL, "image/jpeg", "image/png") self.source.fetch_image(self.candidate, self.settings) - self.assertEqual(os.path.splitext(self.candidate.path)[1], b".png") + assert os.path.splitext(self.candidate.path)[1] == b".png" self.assertExists(self.candidate.path) @@ -241,27 +242,27 @@ def setUp(self): def test_finds_jpg_in_directory(self): _common.touch(os.path.join(self.dpath, b"a.jpg")) candidate = next(self.source.get(None, self.settings, [self.dpath])) - self.assertEqual(candidate.path, os.path.join(self.dpath, b"a.jpg")) + assert candidate.path == os.path.join(self.dpath, b"a.jpg") def test_appropriately_named_file_takes_precedence(self): _common.touch(os.path.join(self.dpath, b"a.jpg")) _common.touch(os.path.join(self.dpath, b"art.jpg")) candidate = next(self.source.get(None, self.settings, [self.dpath])) - self.assertEqual(candidate.path, os.path.join(self.dpath, b"art.jpg")) + assert candidate.path == os.path.join(self.dpath, b"art.jpg") def test_non_image_file_not_identified(self): _common.touch(os.path.join(self.dpath, b"a.txt")) - with self.assertRaises(StopIteration): + with pytest.raises(StopIteration): next(self.source.get(None, self.settings, [self.dpath])) def test_cautious_skips_fallback(self): _common.touch(os.path.join(self.dpath, b"a.jpg")) self.settings.cautious = True - with self.assertRaises(StopIteration): + with pytest.raises(StopIteration): next(self.source.get(None, self.settings, [self.dpath])) def test_empty_dir(self): - with self.assertRaises(StopIteration): + with pytest.raises(StopIteration): next(self.source.get(None, self.settings, [self.dpath])) def test_precedence_amongst_correct_files(self): @@ -274,7 +275,7 @@ def test_precedence_amongst_correct_files(self): candidate.path for candidate in self.source.get(None, self.settings, [self.dpath]) ] - self.assertEqual(candidates, paths) + assert candidates == paths class CombinedTest(FetchImageTestCase, CAAHelper): @@ -294,40 +295,40 @@ def test_main_interface_returns_amazon_art(self): self.mock_response(self.AMAZON_URL) album = _common.Bag(asin=self.ASIN) candidate = self.plugin.art_for_album(album, None) - self.assertIsNotNone(candidate) + assert candidate is not None def test_main_interface_returns_none_for_missing_asin_and_path(self): album = _common.Bag() candidate = self.plugin.art_for_album(album, None) - self.assertIsNone(candidate) + assert candidate is None def test_main_interface_gives_precedence_to_fs_art(self): _common.touch(os.path.join(self.dpath, b"art.jpg")) self.mock_response(self.AMAZON_URL) album = _common.Bag(asin=self.ASIN) candidate = self.plugin.art_for_album(album, [self.dpath]) - self.assertIsNotNone(candidate) - self.assertEqual(candidate.path, os.path.join(self.dpath, b"art.jpg")) + assert candidate is not None + assert candidate.path == os.path.join(self.dpath, b"art.jpg") def test_main_interface_falls_back_to_amazon(self): self.mock_response(self.AMAZON_URL) album = _common.Bag(asin=self.ASIN) candidate = self.plugin.art_for_album(album, [self.dpath]) - self.assertIsNotNone(candidate) - self.assertFalse(candidate.path.startswith(self.dpath)) + assert candidate is not None + assert not candidate.path.startswith(self.dpath) def test_main_interface_tries_amazon_before_aao(self): self.mock_response(self.AMAZON_URL) album = _common.Bag(asin=self.ASIN) self.plugin.art_for_album(album, [self.dpath]) - self.assertEqual(len(responses.calls), 1) - self.assertEqual(responses.calls[0].request.url, self.AMAZON_URL) + assert len(responses.calls) == 1 + assert responses.calls[0].request.url == self.AMAZON_URL def test_main_interface_falls_back_to_aao(self): self.mock_response(self.AMAZON_URL, content_type="text/html") album = _common.Bag(asin=self.ASIN) self.plugin.art_for_album(album, [self.dpath]) - self.assertEqual(responses.calls[-1].request.url, self.AAO_URL) + assert responses.calls[-1].request.url == self.AAO_URL def test_main_interface_uses_caa_when_mbid_available(self): self.mock_caa_response(self.RELEASE_URL, self.RESPONSE_RELEASE) @@ -346,14 +347,14 @@ def test_main_interface_uses_caa_when_mbid_available(self): asin=self.ASIN, ) candidate = self.plugin.art_for_album(album, None) - self.assertIsNotNone(candidate) - self.assertEqual(len(responses.calls), 3) - self.assertEqual(responses.calls[0].request.url, self.RELEASE_URL) + assert candidate is not None + assert len(responses.calls) == 3 + assert responses.calls[0].request.url == self.RELEASE_URL def test_local_only_does_not_access_network(self): album = _common.Bag(mb_albumid=self.MBID, asin=self.ASIN) self.plugin.art_for_album(album, None, local_only=True) - self.assertEqual(len(responses.calls), 0) + assert len(responses.calls) == 0 def test_local_only_gets_fs_image(self): _common.touch(os.path.join(self.dpath, b"art.jpg")) @@ -361,9 +362,9 @@ def test_local_only_gets_fs_image(self): candidate = self.plugin.art_for_album( album, [self.dpath], local_only=True ) - self.assertIsNotNone(candidate) - self.assertEqual(candidate.path, os.path.join(self.dpath, b"art.jpg")) - self.assertEqual(len(responses.calls), 0) + assert candidate is not None + assert candidate.path == os.path.join(self.dpath, b"art.jpg") + assert len(responses.calls) == 0 class AAOTest(UseThePlugin): @@ -393,12 +394,12 @@ def test_aao_scraper_finds_image(self): self.mock_response(self.AAO_URL, body) album = _common.Bag(asin=self.ASIN) candidate = next(self.source.get(album, self.settings, [])) - self.assertEqual(candidate.url, "TARGET_URL") + assert candidate.url == "TARGET_URL" def test_aao_scraper_returns_no_result_when_no_image_present(self): self.mock_response(self.AAO_URL, "blah blah") album = _common.Bag(asin=self.ASIN) - with self.assertRaises(StopIteration): + with pytest.raises(StopIteration): next(self.source.get(album, self.settings, [])) @@ -431,8 +432,8 @@ def test_itunesstore_finds_image(self): }""" self.mock_response(fetchart.ITunesStore.API_URL, json) candidate = next(self.source.get(self.album, self.settings, [])) - self.assertEqual(candidate.url, "url_to_the_image") - self.assertEqual(candidate.match, fetchart.Candidate.MATCH_EXACT) + assert candidate.url == "url_to_the_image" + assert candidate.match == fetchart.Candidate.MATCH_EXACT def test_itunesstore_no_result(self): json = '{"results": []}' @@ -440,9 +441,9 @@ def test_itunesstore_no_result(self): expected = "got no results" with capture_log("beets.test_art") as logs: - with self.assertRaises(StopIteration): + with pytest.raises(StopIteration): next(self.source.get(self.album, self.settings, [])) - self.assertIn(expected, logs[1]) + assert expected in logs[1] def test_itunesstore_requestexception(self): responses.add( @@ -454,9 +455,9 @@ def test_itunesstore_requestexception(self): expected = "iTunes search failed: 404 Client Error" with capture_log("beets.test_art") as logs: - with self.assertRaises(StopIteration): + with pytest.raises(StopIteration): next(self.source.get(self.album, self.settings, [])) - self.assertIn(expected, logs[1]) + assert expected in logs[1] def test_itunesstore_fallback_match(self): json = """{ @@ -470,8 +471,8 @@ def test_itunesstore_fallback_match(self): }""" self.mock_response(fetchart.ITunesStore.API_URL, json) candidate = next(self.source.get(self.album, self.settings, [])) - self.assertEqual(candidate.url, "url_to_the_image") - self.assertEqual(candidate.match, fetchart.Candidate.MATCH_FALLBACK) + assert candidate.url == "url_to_the_image" + assert candidate.match == fetchart.Candidate.MATCH_FALLBACK def test_itunesstore_returns_result_without_artwork(self): json = """{ @@ -487,9 +488,9 @@ def test_itunesstore_returns_result_without_artwork(self): expected = "Malformed itunes candidate" with capture_log("beets.test_art") as logs: - with self.assertRaises(StopIteration): + with pytest.raises(StopIteration): next(self.source.get(self.album, self.settings, [])) - self.assertIn(expected, logs[1]) + assert expected in logs[1] def test_itunesstore_returns_no_result_when_error_received(self): json = '{"error": {"errors": [{"reason": "some reason"}]}}' @@ -497,9 +498,9 @@ def test_itunesstore_returns_no_result_when_error_received(self): expected = "not found in json. Fields are" with capture_log("beets.test_art") as logs: - with self.assertRaises(StopIteration): + with pytest.raises(StopIteration): next(self.source.get(self.album, self.settings, [])) - self.assertIn(expected, logs[1]) + assert expected in logs[1] def test_itunesstore_returns_no_result_with_malformed_response(self): json = """bla blup""" @@ -507,9 +508,9 @@ def test_itunesstore_returns_no_result_with_malformed_response(self): expected = "Could not decode json response:" with capture_log("beets.test_art") as logs: - with self.assertRaises(StopIteration): + with pytest.raises(StopIteration): next(self.source.get(self.album, self.settings, [])) - self.assertIn(expected, logs[1]) + assert expected in logs[1] class GoogleImageTest(UseThePlugin): @@ -532,20 +533,20 @@ def test_google_art_finds_image(self): json = '{"items": [{"link": "url_to_the_image"}]}' self.mock_response(fetchart.GoogleImages.URL, json) candidate = next(self.source.get(album, self.settings, [])) - self.assertEqual(candidate.url, "url_to_the_image") + assert candidate.url == "url_to_the_image" def test_google_art_returns_no_result_when_error_received(self): album = _common.Bag(albumartist="some artist", album="some album") json = '{"error": {"errors": [{"reason": "some reason"}]}}' self.mock_response(fetchart.GoogleImages.URL, json) - with self.assertRaises(StopIteration): + with pytest.raises(StopIteration): next(self.source.get(album, self.settings, [])) def test_google_art_returns_no_result_with_malformed_response(self): album = _common.Bag(albumartist="some artist", album="some album") json = """bla blup""" self.mock_response(fetchart.GoogleImages.URL, json) - with self.assertRaises(StopIteration): + with pytest.raises(StopIteration): next(self.source.get(album, self.settings, [])) @@ -566,9 +567,9 @@ def test_caa_finds_image(self): self.mock_caa_response(self.RELEASE_URL, self.RESPONSE_RELEASE) self.mock_caa_response(self.GROUP_URL, self.RESPONSE_GROUP) candidates = list(self.source.get(album, self.settings, [])) - self.assertEqual(len(candidates), 3) - self.assertEqual(len(responses.calls), 2) - self.assertEqual(responses.calls[0].request.url, self.RELEASE_URL) + assert len(candidates) == 3 + assert len(responses.calls) == 2 + assert responses.calls[0].request.url == self.RELEASE_URL def test_fetchart_uses_caa_pre_sized_maxwidth_thumbs(self): # CAA provides pre-sized thumbnails of width 250px, 500px, and 1200px @@ -582,9 +583,9 @@ def test_fetchart_uses_caa_pre_sized_maxwidth_thumbs(self): self.mock_caa_response(self.RELEASE_URL, self.RESPONSE_RELEASE) self.mock_caa_response(self.GROUP_URL, self.RESPONSE_GROUP) candidates = list(self.source.get(album, self.settings, [])) - self.assertEqual(len(candidates), 3) + assert len(candidates) == 3 for candidate in candidates: - self.assertIn(f"-{maxwidth}.jpg", candidate.url) + assert f"-{maxwidth}.jpg" in candidate.url def test_caa_finds_image_if_maxwidth_is_set_and_thumbnails_is_empty(self): # CAA provides pre-sized thumbnails of width 250px, 500px, and 1200px @@ -603,9 +604,9 @@ def test_caa_finds_image_if_maxwidth_is_set_and_thumbnails_is_empty(self): self.RESPONSE_GROUP_WITHOUT_THUMBNAILS, ) candidates = list(self.source.get(album, self.settings, [])) - self.assertEqual(len(candidates), 3) + assert len(candidates) == 3 for candidate in candidates: - self.assertNotIn(f"-{maxwidth}.jpg", candidate.url) + assert f"-{maxwidth}.jpg" not in candidate.url class FanartTVTest(UseThePlugin): @@ -687,7 +688,7 @@ def test_fanarttv_finds_image(self): self.RESPONSE_MULTIPLE, ) candidate = next(self.source.get(album, self.settings, [])) - self.assertEqual(candidate.url, "http://example.com/1.jpg") + assert candidate.url == "http://example.com/1.jpg" def test_fanarttv_returns_no_result_when_error_received(self): album = _common.Bag(mb_releasegroupid="thereleasegroupid") @@ -695,7 +696,7 @@ def test_fanarttv_returns_no_result_when_error_received(self): fetchart.FanartTV.API_ALBUMS + "thereleasegroupid", self.RESPONSE_ERROR, ) - with self.assertRaises(StopIteration): + with pytest.raises(StopIteration): next(self.source.get(album, self.settings, [])) def test_fanarttv_returns_no_result_with_malformed_response(self): @@ -704,7 +705,7 @@ def test_fanarttv_returns_no_result_with_malformed_response(self): fetchart.FanartTV.API_ALBUMS + "thereleasegroupid", self.RESPONSE_MALFORMED, ) - with self.assertRaises(StopIteration): + with pytest.raises(StopIteration): next(self.source.get(album, self.settings, [])) def test_fanarttv_only_other_images(self): @@ -714,7 +715,7 @@ def test_fanarttv_only_other_images(self): fetchart.FanartTV.API_ALBUMS + "thereleasegroupid", self.RESPONSE_NO_ART, ) - with self.assertRaises(StopIteration): + with pytest.raises(StopIteration): next(self.source.get(album, self.settings, [])) @@ -778,13 +779,12 @@ def _fetch_art(self, should_exist): artpath = self.lib.albums()[0].artpath if should_exist: - self.assertEqual( - artpath, - os.path.join(os.path.dirname(self.i.path), b"cover.jpg"), + assert artpath == os.path.join( + os.path.dirname(self.i.path), b"cover.jpg" ) self.assertExists(artpath) else: - self.assertEqual(artpath, None) + assert artpath is None return artpath def test_fetch_art(self): @@ -869,11 +869,11 @@ def _assertImageIsValidArt(self, image_file, should_exist): # noqa candidate = self.plugin.art_for_album(self.album, [""], True) if should_exist: - self.assertNotEqual(candidate, None) - self.assertEqual(candidate.path, self.image_file) + assert candidate is not None + assert candidate.path == self.image_file self.assertExists(candidate.path) else: - self.assertIsNone(candidate) + assert candidate is None def _assert_image_operated(self, image_file, operation, should_operate): self.image_file = image_file @@ -881,7 +881,7 @@ def _assert_image_operated(self, image_file, operation, should_operate): ArtResizer.shared, operation, return_value=self.image_file ) as mock_operation: self.plugin.art_for_album(self.album, [""], True) - self.assertEqual(mock_operation.called, should_operate) + assert mock_operation.called == should_operate def _require_backend(self): """Skip the test if the art resizer doesn't have ImageMagick or @@ -991,7 +991,7 @@ def setUp(self): self.plugin = fetchart.FetchArtPlugin() def test_moves_filesystem_to_end(self): - self.assertEqual(type(self.plugin.sources[-1]), fetchart.FileSystem) + assert type(self.plugin.sources[-1]) == fetchart.FileSystem class EnforceRatioConfigTest(BeetsTestCase): @@ -1001,7 +1001,7 @@ def _load_with_config(self, values, should_raise): if should_raise: for v in values: config["fetchart"]["enforce_ratio"] = v - with self.assertRaises(confuse.ConfigValueError): + with pytest.raises(confuse.ConfigValueError): fetchart.FetchArtPlugin() else: for v in values: diff --git a/test/plugins/test_bareasc.py b/test/plugins/test_bareasc.py index 393d686c89..624392dbfd 100644 --- a/test/plugins/test_bareasc.py +++ b/test/plugins/test_bareasc.py @@ -62,16 +62,14 @@ def test_bareasc_search(self): for query, expected_titles in test_cases: with self.subTest(query=query, expected_titles=expected_titles): items = self.lib.items(query) - self.assertListEqual( - [item.title for item in items], expected_titles - ) + assert [item.title for item in items] == expected_titles def test_bareasc_list_output(self): """Bare-ASCII version of list command - check output.""" with capture_stdout() as output: self.run_command("bareasc", "with accents") - self.assertIn("Antonin Dvorak", output.getvalue()) + assert "Antonin Dvorak" in output.getvalue() def test_bareasc_format_output(self): """Bare-ASCII version of list -f command - check output.""" @@ -80,4 +78,4 @@ def test_bareasc_format_output(self): "bareasc", "with accents", "-f", "$artist:: $title" ) - self.assertEqual("Antonin Dvorak:: with accents\n", output.getvalue()) + assert "Antonin Dvorak:: with accents\n" == output.getvalue() diff --git a/test/plugins/test_beatport.py b/test/plugins/test_beatport.py index e988c9b4c4..d072340b5e 100644 --- a/test/plugins/test_beatport.py +++ b/test/plugins/test_beatport.py @@ -12,8 +12,7 @@ # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. -"""Tests for the 'beatport' plugin. -""" +"""Tests for the 'beatport' plugin.""" from datetime import timedelta @@ -530,38 +529,32 @@ def mk_test_album(self): # Test BeatportRelease. def test_album_name_applied(self): - self.assertEqual(self.album.name, self.test_album["album"]) + assert self.album.name == self.test_album["album"] def test_catalog_number_applied(self): - self.assertEqual( - self.album.catalog_number, self.test_album["catalognum"] - ) + assert self.album.catalog_number == self.test_album["catalognum"] def test_label_applied(self): - self.assertEqual(self.album.label_name, self.test_album["label"]) + assert self.album.label_name == self.test_album["label"] def test_category_applied(self): - self.assertEqual(self.album.category, "Release") + assert self.album.category == "Release" def test_album_url_applied(self): - self.assertEqual( - self.album.url, "https://beatport.com/release/charade/1742984" - ) + assert self.album.url == "https://beatport.com/release/charade/1742984" # Test BeatportTrack. def test_title_applied(self): for track, test_track in zip(self.tracks, self.test_tracks): - self.assertEqual(track.name, test_track.title) + assert track.name == test_track.title def test_mix_name_applied(self): for track, test_track in zip(self.tracks, self.test_tracks): - self.assertEqual(track.mix_name, test_track.mix_name) + assert track.mix_name == test_track.mix_name def test_length_applied(self): for track, test_track in zip(self.tracks, self.test_tracks): - self.assertEqual( - int(track.length.total_seconds()), int(test_track.length) - ) + assert int(track.length.total_seconds()) == int(test_track.length) def test_track_url_applied(self): # Specify beatport ids here because an 'item.id' is beets-internal. @@ -575,22 +568,21 @@ def test_track_url_applied(self): ] # Concatenate with 'id' to pass strict equality test. for track, test_track, id in zip(self.tracks, self.test_tracks, ids): - self.assertEqual( - track.url, - "https://beatport.com/track/" + test_track.url + "/" + str(id), + assert ( + track.url == f"https://beatport.com/track/{test_track.url}/{id}" ) def test_bpm_applied(self): for track, test_track in zip(self.tracks, self.test_tracks): - self.assertEqual(track.bpm, test_track.bpm) + assert track.bpm == test_track.bpm def test_initial_key_applied(self): for track, test_track in zip(self.tracks, self.test_tracks): - self.assertEqual(track.initial_key, test_track.initial_key) + assert track.initial_key == test_track.initial_key def test_genre_applied(self): for track, test_track in zip(self.tracks, self.test_tracks): - self.assertEqual(track.genre, test_track.genre) + assert track.genre == test_track.genre class BeatportResponseEmptyTest(BeetsTestCase): @@ -632,7 +624,7 @@ def setUp(self): def test_response_tracks_empty(self): response_tracks = [] tracks = [beatport.BeatportTrack(t) for t in response_tracks] - self.assertEqual(tracks, []) + assert tracks == [] def test_sub_genre_empty_fallback(self): """No 'sub_genre' is provided. Test if fallback to 'genre' works.""" @@ -641,9 +633,7 @@ def test_sub_genre_empty_fallback(self): self.test_tracks[0]["subGenres"] = [] - self.assertEqual( - tracks[0].genre, self.test_tracks[0]["genres"][0]["name"] - ) + assert tracks[0].genre == self.test_tracks[0]["genres"][0]["name"] def test_genre_empty(self): """No 'genre' is provided. Test if 'sub_genre' is applied.""" @@ -652,6 +642,4 @@ def test_genre_empty(self): self.test_tracks[0]["genres"] = [] - self.assertEqual( - tracks[0].genre, self.test_tracks[0]["subGenres"][0]["name"] - ) + assert tracks[0].genre == self.test_tracks[0]["subGenres"][0]["name"] diff --git a/test/plugins/test_bucket.py b/test/plugins/test_bucket.py index 4a16fd9949..bc764038e0 100644 --- a/test/plugins/test_bucket.py +++ b/test/plugins/test_bucket.py @@ -15,6 +15,8 @@ """Tests for the 'bucket' plugin.""" +import pytest + from beets import config, ui from beets.test.helper import BeetsTestCase from beetsplug import bucket @@ -42,74 +44,74 @@ def test_year_single_year(self): """If a single year is given, range starts from this year and stops at the year preceding the one of next bucket.""" self._setup_config(bucket_year=["1950s", "1970s"]) - self.assertEqual(self.plugin._tmpl_bucket("1959"), "1950s") - self.assertEqual(self.plugin._tmpl_bucket("1969"), "1950s") + assert self.plugin._tmpl_bucket("1959") == "1950s" + assert self.plugin._tmpl_bucket("1969") == "1950s" def test_year_single_year_last_folder(self): """If a single year is given for the last bucket, extend it to current year.""" self._setup_config(bucket_year=["1950", "1970"]) - self.assertEqual(self.plugin._tmpl_bucket("2014"), "1970") - self.assertEqual(self.plugin._tmpl_bucket("2025"), "2025") + assert self.plugin._tmpl_bucket("2014") == "1970" + assert self.plugin._tmpl_bucket("2025") == "2025" def test_year_two_years(self): """Buckets can be named with the 'from-to' syntax.""" self._setup_config(bucket_year=["1950-59", "1960-1969"]) - self.assertEqual(self.plugin._tmpl_bucket("1959"), "1950-59") - self.assertEqual(self.plugin._tmpl_bucket("1969"), "1960-1969") + assert self.plugin._tmpl_bucket("1959") == "1950-59" + assert self.plugin._tmpl_bucket("1969") == "1960-1969" def test_year_multiple_years(self): """Buckets can be named by listing all the years""" self._setup_config(bucket_year=["1950,51,52,53"]) - self.assertEqual(self.plugin._tmpl_bucket("1953"), "1950,51,52,53") - self.assertEqual(self.plugin._tmpl_bucket("1974"), "1974") + assert self.plugin._tmpl_bucket("1953") == "1950,51,52,53" + assert self.plugin._tmpl_bucket("1974") == "1974" def test_year_out_of_range(self): """If no range match, return the year""" self._setup_config(bucket_year=["1950-59", "1960-69"]) - self.assertEqual(self.plugin._tmpl_bucket("1974"), "1974") + assert self.plugin._tmpl_bucket("1974") == "1974" self._setup_config(bucket_year=[]) - self.assertEqual(self.plugin._tmpl_bucket("1974"), "1974") + assert self.plugin._tmpl_bucket("1974") == "1974" def test_year_out_of_range_extrapolate(self): """If no defined range match, extrapolate all ranges using the most common syntax amongst existing buckets and return the matching one.""" self._setup_config(bucket_year=["1950-59", "1960-69"], extrapolate=True) - self.assertEqual(self.plugin._tmpl_bucket("1914"), "1910-19") + assert self.plugin._tmpl_bucket("1914") == "1910-19" # pick single year format self._setup_config( bucket_year=["1962-81", "2002", "2012"], extrapolate=True ) - self.assertEqual(self.plugin._tmpl_bucket("1983"), "1982") + assert self.plugin._tmpl_bucket("1983") == "1982" # pick from-end format self._setup_config( bucket_year=["1962-81", "2002", "2012-14"], extrapolate=True ) - self.assertEqual(self.plugin._tmpl_bucket("1983"), "1982-01") + assert self.plugin._tmpl_bucket("1983") == "1982-01" # extrapolate add ranges, but never modifies existing ones self._setup_config( bucket_year=["1932", "1942", "1952", "1962-81", "2002"], extrapolate=True, ) - self.assertEqual(self.plugin._tmpl_bucket("1975"), "1962-81") + assert self.plugin._tmpl_bucket("1975") == "1962-81" def test_alpha_all_chars(self): """Alphabet buckets can be named by listing all their chars""" self._setup_config(bucket_alpha=["ABCD", "FGH", "IJKL"]) - self.assertEqual(self.plugin._tmpl_bucket("garry"), "FGH") + assert self.plugin._tmpl_bucket("garry") == "FGH" def test_alpha_first_last_chars(self): """Alphabet buckets can be named by listing the 'from-to' syntax""" self._setup_config(bucket_alpha=["0->9", "A->D", "F-H", "I->Z"]) - self.assertEqual(self.plugin._tmpl_bucket("garry"), "F-H") - self.assertEqual(self.plugin._tmpl_bucket("2pac"), "0->9") + assert self.plugin._tmpl_bucket("garry") == "F-H" + assert self.plugin._tmpl_bucket("2pac") == "0->9" def test_alpha_out_of_range(self): """If no range match, return the initial""" self._setup_config(bucket_alpha=["ABCD", "FGH", "IJKL"]) - self.assertEqual(self.plugin._tmpl_bucket("errol"), "E") + assert self.plugin._tmpl_bucket("errol") == "E" self._setup_config(bucket_alpha=[]) - self.assertEqual(self.plugin._tmpl_bucket("errol"), "E") + assert self.plugin._tmpl_bucket("errol") == "E" def test_alpha_regex(self): """Check regex is used""" @@ -117,10 +119,10 @@ def test_alpha_regex(self): bucket_alpha=["foo", "bar"], bucket_alpha_regex={"foo": "^[a-d]", "bar": "^[e-z]"}, ) - self.assertEqual(self.plugin._tmpl_bucket("alpha"), "foo") - self.assertEqual(self.plugin._tmpl_bucket("delta"), "foo") - self.assertEqual(self.plugin._tmpl_bucket("zeta"), "bar") - self.assertEqual(self.plugin._tmpl_bucket("Alpha"), "A") + assert self.plugin._tmpl_bucket("alpha") == "foo" + assert self.plugin._tmpl_bucket("delta") == "foo" + assert self.plugin._tmpl_bucket("zeta") == "bar" + assert self.plugin._tmpl_bucket("Alpha") == "A" def test_alpha_regex_mix(self): """Check mixing regex and non-regex is possible""" @@ -128,35 +130,35 @@ def test_alpha_regex_mix(self): bucket_alpha=["A - D", "E - L"], bucket_alpha_regex={"A - D": "^[0-9a-dA-D…äÄ]"}, ) - self.assertEqual(self.plugin._tmpl_bucket("alpha"), "A - D") - self.assertEqual(self.plugin._tmpl_bucket("Ärzte"), "A - D") - self.assertEqual(self.plugin._tmpl_bucket("112"), "A - D") - self.assertEqual(self.plugin._tmpl_bucket("…and Oceans"), "A - D") - self.assertEqual(self.plugin._tmpl_bucket("Eagles"), "E - L") + assert self.plugin._tmpl_bucket("alpha") == "A - D" + assert self.plugin._tmpl_bucket("Ärzte") == "A - D" + assert self.plugin._tmpl_bucket("112") == "A - D" + assert self.plugin._tmpl_bucket("…and Oceans") == "A - D" + assert self.plugin._tmpl_bucket("Eagles") == "E - L" def test_bad_alpha_range_def(self): """If bad alpha range definition, a UserError is raised.""" - with self.assertRaises(ui.UserError): + with pytest.raises(ui.UserError): self._setup_config(bucket_alpha=["$%"]) def test_bad_year_range_def_no4digits(self): """If bad year range definition, a UserError is raised. Range origin must be expressed on 4 digits. """ - with self.assertRaises(ui.UserError): + with pytest.raises(ui.UserError): self._setup_config(bucket_year=["62-64"]) def test_bad_year_range_def_nodigits(self): """If bad year range definition, a UserError is raised. At least the range origin must be declared. """ - with self.assertRaises(ui.UserError): + with pytest.raises(ui.UserError): self._setup_config(bucket_year=["nodigits"]) def check_span_from_str(self, sstr, dfrom, dto): d = bucket.span_from_str(sstr) - self.assertEqual(dfrom, d["from"]) - self.assertEqual(dto, d["to"]) + assert dfrom == d["from"] + assert dto == d["to"] def test_span_from_str(self): self.check_span_from_str("1980 2000", 1980, 2000) diff --git a/test/plugins/test_convert.py b/test/plugins/test_convert.py index a60cb531a9..67f6fcd04e 100644 --- a/test/plugins/test_convert.py +++ b/test/plugins/test_convert.py @@ -64,13 +64,9 @@ def assertFileTag(self, path, tag): # noqa self.assertIsFile(path) with open(path, "rb") as f: f.seek(-len(display_tag), os.SEEK_END) - self.assertEqual( - f.read(), - tag, - "{} is not tagged with {}".format( - displayable_path(path), display_tag - ), - ) + assert ( + f.read() == tag + ), f"{displayable_path(path)} is not tagged with {display_tag}" def assertNoFileTag(self, path, tag): # noqa """Assert that the path is a file and the files content does not @@ -81,13 +77,9 @@ def assertNoFileTag(self, path, tag): # noqa self.assertIsFile(path) with open(path, "rb") as f: f.seek(-len(tag), os.SEEK_END) - self.assertNotEqual( - f.read(), - tag, - "{} is unexpectedly tagged with {}".format( - displayable_path(path), display_tag - ), - ) + assert ( + f.read() != tag + ), f"{displayable_path(path)} is unexpectedly tagged with {display_tag}" class ConvertTestCase(ConvertMixin, PluginTestCase): @@ -121,7 +113,7 @@ def test_import_original_on_convert_error(self): self.run_asis_importer() item = self.lib.items().get() - self.assertIsNotNone(item) + assert item is not None self.assertIsFile(item.path) def test_delete_originals(self): @@ -129,13 +121,9 @@ def test_delete_originals(self): self.run_asis_importer() for path in self.importer.paths: for root, dirnames, filenames in os.walk(path): - self.assertEqual( - len(fnmatch.filter(filenames, "*.mp3")), - 0, - "Non-empty import directory {}".format( - util.displayable_path(path) - ), - ) + assert ( + len(fnmatch.filter(filenames, "*.mp3")) == 0 + ), f"Non-empty import directory {util.displayable_path(path)}" def get_count_of_import_files(self): import_file_count = 0 @@ -208,13 +196,13 @@ def test_reject_confirmation(self): self.assertNotExists(converted) def test_convert_keep_new(self): - self.assertEqual(os.path.splitext(self.item.path)[1], b".ogg") + assert os.path.splitext(self.item.path)[1] == b".ogg" with control_stdin("y"): self.run_convert("--keep-new") self.item.load() - self.assertEqual(os.path.splitext(self.item.path)[1], b".mp3") + assert os.path.splitext(self.item.path)[1] == b".mp3" def test_format_option(self): with control_stdin("y"): @@ -234,14 +222,14 @@ def test_embed_album_art(self): self.run_convert() converted = os.path.join(self.convert_dest, b"converted.mp3") mediafile = MediaFile(converted) - self.assertEqual(mediafile.images[0].data, image_data) + assert mediafile.images[0].data == image_data def test_skip_existing(self): converted = os.path.join(self.convert_dest, b"converted.mp3") self.touch(converted, content="XXX") self.run_convert("--yes") with open(converted) as f: - self.assertEqual(f.read(), "XXX") + assert f.read() == "XXX" def test_pretend(self): self.run_convert("--pretend") @@ -251,7 +239,7 @@ def test_pretend(self): def test_empty_query(self): with capture_log("beets.convert") as logs: self.run_convert("An impossible query") - self.assertEqual(logs[0], "convert: Empty query result.") + assert logs[0] == "convert: Empty query result." def test_no_transcode_when_maxbr_set_high_and_different_formats(self): self.config["convert"]["max_bitrate"] = 5000 @@ -300,12 +288,12 @@ def test_playlist(self): with control_stdin("y"): self.run_convert("--playlist", "playlist.m3u8") m3u_created = os.path.join(self.convert_dest, b"playlist.m3u8") - self.assertTrue(os.path.exists(m3u_created)) + assert os.path.exists(m3u_created) def test_playlist_pretend(self): self.run_convert("--playlist", "playlist.m3u8", "--pretend") m3u_created = os.path.join(self.convert_dest, b"playlist.m3u8") - self.assertFalse(os.path.exists(m3u_created)) + assert not os.path.exists(m3u_created) @_common.slow_test() diff --git a/test/plugins/test_discogs.py b/test/plugins/test_discogs.py index 416ca02767..634b3cdb96 100644 --- a/test/plugins/test_discogs.py +++ b/test/plugins/test_discogs.py @@ -94,59 +94,59 @@ def test_parse_media_for_tracks(self): d = DiscogsPlugin().get_album_info(release) t = d.tracks - self.assertEqual(d.media, "FORMAT") - self.assertEqual(t[0].media, d.media) - self.assertEqual(t[1].media, d.media) + assert d.media == "FORMAT" + assert t[0].media == d.media + assert t[1].media == d.media def test_parse_medium_numbers_single_medium(self): release = self._make_release_from_positions(["1", "2"]) d = DiscogsPlugin().get_album_info(release) t = d.tracks - self.assertEqual(d.mediums, 1) - self.assertEqual(t[0].medium, 1) - self.assertEqual(t[0].medium_total, 2) - self.assertEqual(t[1].medium, 1) - self.assertEqual(t[0].medium_total, 2) + assert d.mediums == 1 + assert t[0].medium == 1 + assert t[0].medium_total == 2 + assert t[1].medium == 1 + assert t[0].medium_total == 2 def test_parse_medium_numbers_two_mediums(self): release = self._make_release_from_positions(["1-1", "2-1"]) d = DiscogsPlugin().get_album_info(release) t = d.tracks - self.assertEqual(d.mediums, 2) - self.assertEqual(t[0].medium, 1) - self.assertEqual(t[0].medium_total, 1) - self.assertEqual(t[1].medium, 2) - self.assertEqual(t[1].medium_total, 1) + assert d.mediums == 2 + assert t[0].medium == 1 + assert t[0].medium_total == 1 + assert t[1].medium == 2 + assert t[1].medium_total == 1 def test_parse_medium_numbers_two_mediums_two_sided(self): release = self._make_release_from_positions(["A1", "B1", "C1"]) d = DiscogsPlugin().get_album_info(release) t = d.tracks - self.assertEqual(d.mediums, 2) - self.assertEqual(t[0].medium, 1) - self.assertEqual(t[0].medium_total, 2) - self.assertEqual(t[0].medium_index, 1) - self.assertEqual(t[1].medium, 1) - self.assertEqual(t[1].medium_total, 2) - self.assertEqual(t[1].medium_index, 2) - self.assertEqual(t[2].medium, 2) - self.assertEqual(t[2].medium_total, 1) - self.assertEqual(t[2].medium_index, 1) + assert d.mediums == 2 + assert t[0].medium == 1 + assert t[0].medium_total == 2 + assert t[0].medium_index == 1 + assert t[1].medium == 1 + assert t[1].medium_total == 2 + assert t[1].medium_index == 2 + assert t[2].medium == 2 + assert t[2].medium_total == 1 + assert t[2].medium_index == 1 def test_parse_track_indices(self): release = self._make_release_from_positions(["1", "2"]) d = DiscogsPlugin().get_album_info(release) t = d.tracks - self.assertEqual(t[0].medium_index, 1) - self.assertEqual(t[0].index, 1) - self.assertEqual(t[0].medium_total, 2) - self.assertEqual(t[1].medium_index, 2) - self.assertEqual(t[1].index, 2) - self.assertEqual(t[1].medium_total, 2) + assert t[0].medium_index == 1 + assert t[0].index == 1 + assert t[0].medium_total == 2 + assert t[1].medium_index == 2 + assert t[1].index == 2 + assert t[1].medium_total == 2 def test_parse_track_indices_several_media(self): release = self._make_release_from_positions( @@ -155,19 +155,19 @@ def test_parse_track_indices_several_media(self): d = DiscogsPlugin().get_album_info(release) t = d.tracks - self.assertEqual(d.mediums, 3) - self.assertEqual(t[0].medium_index, 1) - self.assertEqual(t[0].index, 1) - self.assertEqual(t[0].medium_total, 2) - self.assertEqual(t[1].medium_index, 2) - self.assertEqual(t[1].index, 2) - self.assertEqual(t[1].medium_total, 2) - self.assertEqual(t[2].medium_index, 1) - self.assertEqual(t[2].index, 3) - self.assertEqual(t[2].medium_total, 1) - self.assertEqual(t[3].medium_index, 1) - self.assertEqual(t[3].index, 4) - self.assertEqual(t[3].medium_total, 1) + assert d.mediums == 3 + assert t[0].medium_index == 1 + assert t[0].index == 1 + assert t[0].medium_total == 2 + assert t[1].medium_index == 2 + assert t[1].index == 2 + assert t[1].medium_total == 2 + assert t[2].medium_index == 1 + assert t[2].index == 3 + assert t[2].medium_total == 1 + assert t[3].medium_index == 1 + assert t[3].index == 4 + assert t[3].medium_total == 1 def test_parse_position(self): """Test the conversion of discogs `position` to medium, medium_index @@ -188,31 +188,31 @@ def test_parse_position(self): d = DiscogsPlugin() for position, expected in positions: - self.assertEqual(d.get_track_index(position), expected) + assert d.get_track_index(position) == expected def test_parse_tracklist_without_sides(self): """Test standard Discogs position 12.2.9#1: "without sides".""" release = self._make_release_from_positions(["1", "2", "3"]) d = DiscogsPlugin().get_album_info(release) - self.assertEqual(d.mediums, 1) - self.assertEqual(len(d.tracks), 3) + assert d.mediums == 1 + assert len(d.tracks) == 3 def test_parse_tracklist_with_sides(self): """Test standard Discogs position 12.2.9#2: "with sides".""" release = self._make_release_from_positions(["A1", "A2", "B1", "B2"]) d = DiscogsPlugin().get_album_info(release) - self.assertEqual(d.mediums, 1) # 2 sides = 1 LP - self.assertEqual(len(d.tracks), 4) + assert d.mediums == 1 # 2 sides = 1 LP + assert len(d.tracks) == 4 def test_parse_tracklist_multiple_lp(self): """Test standard Discogs position 12.2.9#3: "multiple LP".""" release = self._make_release_from_positions(["A1", "A2", "B1", "C1"]) d = DiscogsPlugin().get_album_info(release) - self.assertEqual(d.mediums, 2) # 3 sides = 1 LP + 1 LP - self.assertEqual(len(d.tracks), 4) + assert d.mediums == 2 # 3 sides = 1 LP + 1 LP + assert len(d.tracks) == 4 def test_parse_tracklist_multiple_cd(self): """Test standard Discogs position 12.2.9#4: "multiple CDs".""" @@ -221,56 +221,56 @@ def test_parse_tracklist_multiple_cd(self): ) d = DiscogsPlugin().get_album_info(release) - self.assertEqual(d.mediums, 3) - self.assertEqual(len(d.tracks), 4) + assert d.mediums == 3 + assert len(d.tracks) == 4 def test_parse_tracklist_non_standard(self): """Test non standard Discogs position.""" release = self._make_release_from_positions(["I", "II", "III", "IV"]) d = DiscogsPlugin().get_album_info(release) - self.assertEqual(d.mediums, 1) - self.assertEqual(len(d.tracks), 4) + assert d.mediums == 1 + assert len(d.tracks) == 4 def test_parse_tracklist_subtracks_dot(self): """Test standard Discogs position 12.2.9#5: "sub tracks, dots".""" release = self._make_release_from_positions(["1", "2.1", "2.2", "3"]) d = DiscogsPlugin().get_album_info(release) - self.assertEqual(d.mediums, 1) - self.assertEqual(len(d.tracks), 3) + assert d.mediums == 1 + assert len(d.tracks) == 3 release = self._make_release_from_positions( ["A1", "A2.1", "A2.2", "A3"] ) d = DiscogsPlugin().get_album_info(release) - self.assertEqual(d.mediums, 1) - self.assertEqual(len(d.tracks), 3) + assert d.mediums == 1 + assert len(d.tracks) == 3 def test_parse_tracklist_subtracks_letter(self): """Test standard Discogs position 12.2.9#5: "sub tracks, letter".""" release = self._make_release_from_positions(["A1", "A2a", "A2b", "A3"]) d = DiscogsPlugin().get_album_info(release) - self.assertEqual(d.mediums, 1) - self.assertEqual(len(d.tracks), 3) + assert d.mediums == 1 + assert len(d.tracks) == 3 release = self._make_release_from_positions( ["A1", "A2.a", "A2.b", "A3"] ) d = DiscogsPlugin().get_album_info(release) - self.assertEqual(d.mediums, 1) - self.assertEqual(len(d.tracks), 3) + assert d.mediums == 1 + assert len(d.tracks) == 3 def test_parse_tracklist_subtracks_extra_material(self): """Test standard Discogs position 12.2.9#6: "extra material".""" release = self._make_release_from_positions(["1", "2", "Video 1"]) d = DiscogsPlugin().get_album_info(release) - self.assertEqual(d.mediums, 2) - self.assertEqual(len(d.tracks), 3) + assert d.mediums == 2 + assert len(d.tracks) == 3 def test_parse_tracklist_subtracks_indices(self): """Test parsing of subtracks that include index tracks.""" @@ -281,10 +281,10 @@ def test_parse_tracklist_subtracks_indices(self): release.data["tracklist"][1]["title"] = "TRACK GROUP TITLE" d = DiscogsPlugin().get_album_info(release) - self.assertEqual(d.mediums, 1) - self.assertEqual(d.tracks[0].disctitle, "MEDIUM TITLE") - self.assertEqual(len(d.tracks), 1) - self.assertEqual(d.tracks[0].title, "TRACK GROUP TITLE") + assert d.mediums == 1 + assert d.tracks[0].disctitle == "MEDIUM TITLE" + assert len(d.tracks) == 1 + assert d.tracks[0].title == "TRACK GROUP TITLE" def test_parse_tracklist_subtracks_nested_logical(self): """Test parsing of subtracks defined inside a index track that are @@ -299,9 +299,9 @@ def test_parse_tracklist_subtracks_nested_logical(self): ] d = DiscogsPlugin().get_album_info(release) - self.assertEqual(d.mediums, 1) - self.assertEqual(len(d.tracks), 3) - self.assertEqual(d.tracks[1].title, "TRACK GROUP TITLE") + assert d.mediums == 1 + assert len(d.tracks) == 3 + assert d.tracks[1].title == "TRACK GROUP TITLE" def test_parse_tracklist_subtracks_nested_physical(self): """Test parsing of subtracks defined inside a index track that are @@ -316,10 +316,10 @@ def test_parse_tracklist_subtracks_nested_physical(self): ] d = DiscogsPlugin().get_album_info(release) - self.assertEqual(d.mediums, 1) - self.assertEqual(len(d.tracks), 4) - self.assertEqual(d.tracks[1].title, "TITLE ONE") - self.assertEqual(d.tracks[2].title, "TITLE TWO") + assert d.mediums == 1 + assert len(d.tracks) == 4 + assert d.tracks[1].title == "TITLE ONE" + assert d.tracks[2].title == "TITLE TWO" def test_parse_tracklist_disctitles(self): """Test parsing of index tracks that act as disc titles.""" @@ -332,11 +332,11 @@ def test_parse_tracklist_disctitles(self): release.data["tracklist"][3]["title"] = "MEDIUM TITLE CD2" d = DiscogsPlugin().get_album_info(release) - self.assertEqual(d.mediums, 2) - self.assertEqual(d.tracks[0].disctitle, "MEDIUM TITLE CD1") - self.assertEqual(d.tracks[1].disctitle, "MEDIUM TITLE CD1") - self.assertEqual(d.tracks[2].disctitle, "MEDIUM TITLE CD2") - self.assertEqual(len(d.tracks), 3) + assert d.mediums == 2 + assert d.tracks[0].disctitle == "MEDIUM TITLE CD1" + assert d.tracks[1].disctitle == "MEDIUM TITLE CD1" + assert d.tracks[2].disctitle == "MEDIUM TITLE CD2" + assert len(d.tracks) == 3 def test_parse_minimal_release(self): """Test parsing of a release with the minimal amount of information.""" @@ -353,9 +353,9 @@ def test_parse_minimal_release(self): artists=[Bag(data=d) for d in data["artists"]], ) d = DiscogsPlugin().get_album_info(release) - self.assertEqual(d.artist, "ARTIST NAME") - self.assertEqual(d.album, "TITLE") - self.assertEqual(len(d.tracks), 1) + assert d.artist == "ARTIST NAME" + assert d.album == "TITLE" + assert len(d.tracks) == 1 def test_parse_release_without_required_fields(self): """Test parsing of a release that does not have the required fields.""" @@ -363,8 +363,8 @@ def test_parse_release_without_required_fields(self): with capture_log() as logs: d = DiscogsPlugin().get_album_info(release) - self.assertEqual(d, None) - self.assertIn("Release does not contain the required fields", logs[0]) + assert d is None + assert "Release does not contain the required fields" in logs[0] def test_album_for_id(self): """Test parsing for a valid Discogs release_id""" @@ -395,15 +395,15 @@ def test_album_for_id(self): match = extract_discogs_id_regex(test_pattern) if not match: match = "" - self.assertEqual(match, expected) + assert match == expected def test_default_genre_style_settings(self): """Test genre default settings, genres to genre, styles to style""" release = self._make_release_from_positions(["1", "2"]) d = DiscogsPlugin().get_album_info(release) - self.assertEqual(d.genre, "GENRE1, GENRE2") - self.assertEqual(d.style, "STYLE1, STYLE2") + assert d.genre == "GENRE1, GENRE2" + assert d.style == "STYLE1, STYLE2" def test_append_style_to_genre(self): """Test appending style to genre if config enabled""" @@ -411,8 +411,8 @@ def test_append_style_to_genre(self): release = self._make_release_from_positions(["1", "2"]) d = DiscogsPlugin().get_album_info(release) - self.assertEqual(d.genre, "GENRE1, GENRE2, STYLE1, STYLE2") - self.assertEqual(d.style, "STYLE1, STYLE2") + assert d.genre == "GENRE1, GENRE2, STYLE1, STYLE2" + assert d.style == "STYLE1, STYLE2" def test_append_style_to_genre_no_style(self): """Test nothing appended to genre if style is empty""" @@ -421,5 +421,5 @@ def test_append_style_to_genre_no_style(self): release.data["styles"] = [] d = DiscogsPlugin().get_album_info(release) - self.assertEqual(d.genre, "GENRE1, GENRE2") - self.assertEqual(d.style, None) + assert d.genre == "GENRE1, GENRE2" + assert d.style is None diff --git a/test/plugins/test_edit.py b/test/plugins/test_edit.py index e15caaa57d..beeb649a35 100644 --- a/test/plugins/test_edit.py +++ b/test/plugins/test_edit.py @@ -94,7 +94,7 @@ def assertItemFieldsModified( # noqa for field in lib_item._fields if lib_item[field] != item[field] ] - self.assertEqual(set(diff_fields).difference(allowed), set(fields)) + assert set(diff_fields).difference(allowed) == set(fields) def run_mocked_interpreter(self, modify_file_args={}, stdin=[]): """Run the edit command during an import session, with mocked stdin and @@ -143,11 +143,11 @@ def assertCounts( # noqa title_starts_with="", ): """Several common assertions on Album, Track and call counts.""" - self.assertEqual(len(self.lib.albums()), album_count) - self.assertEqual(len(self.lib.items()), track_count) - self.assertEqual(mock_write.call_count, write_call_count) - self.assertTrue( - all(i.title.startswith(title_starts_with) for i in self.lib.items()) + assert len(self.lib.albums()) == album_count + assert len(self.lib.items()) == track_count + assert mock_write.call_count == write_call_count + assert all( + i.title.startswith(title_starts_with) for i in self.lib.items() ) def test_title_edit_discard(self, mock_write): @@ -199,9 +199,7 @@ def test_single_title_edit_apply(self, mock_write): self.assertItemFieldsModified( list(self.album.items())[:-1], self.items_orig[:-1], [] ) - self.assertEqual( - list(self.album.items())[-1].title, "modified t\u00eftle 9" - ) + assert list(self.album.items())[-1].title == "modified t\u00eftle 9" def test_noedit(self, mock_write): """Do not edit anything.""" @@ -234,7 +232,7 @@ def test_album_edit_apply(self, mock_write): ) # Ensure album is *not* modified. self.album.load() - self.assertEqual(self.album.album, "\u00e4lbum") + assert self.album.album == "\u00e4lbum" def test_single_edit_add_field(self, mock_write): """Edit the yaml file appending an extra field to the first item, then @@ -247,7 +245,7 @@ def test_single_edit_add_field(self, mock_write): ["a"], ) - self.assertEqual(self.lib.items("id:2")[0].foo, "bar") + assert self.lib.items("id:2")[0].foo == "bar" # Even though a flexible attribute was written (which is not directly # written to the tags), write should still be called since templates # might use it. @@ -266,7 +264,7 @@ def test_a_album_edit_apply(self, mock_write): self.album.load() self.assertCounts(mock_write, write_call_count=self.TRACK_COUNT) - self.assertEqual(self.album.album, "modified \u00e4lbum") + assert self.album.album == "modified \u00e4lbum" self.assertItemFieldsModified( self.album.items(), self.items_orig, ["album", "mtime"] ) @@ -282,7 +280,7 @@ def test_a_albumartist_edit_apply(self, mock_write): self.album.load() self.assertCounts(mock_write, write_call_count=self.TRACK_COUNT) - self.assertEqual(self.album.albumartist, "the modified album artist") + assert self.album.albumartist == "the modified album artist" self.assertItemFieldsModified( self.album.items(), self.items_orig, ["albumartist", "mtime"] ) @@ -366,12 +364,10 @@ def test_edit_apply_asis(self): "mb_albumartistids", ], ) - self.assertTrue( - all("Edited Track" in i.title for i in self.lib.items()) - ) + assert all("Edited Track" in i.title for i in self.lib.items()) # Ensure album is *not* fetched from a candidate. - self.assertEqual(self.lib.albums()[0].mb_albumid, "") + assert self.lib.albums()[0].mb_albumid == "" def test_edit_discard_asis(self): """Edit the album field for all items in the library, discard changes, @@ -391,10 +387,10 @@ def test_edit_discard_asis(self): [], self.IGNORED + ["albumartist", "mb_albumartistid"], ) - self.assertTrue(all("Tag Track" in i.title for i in self.lib.items())) + assert all("Tag Track" in i.title for i in self.lib.items()) # Ensure album is *not* fetched from a candidate. - self.assertEqual(self.lib.albums()[0].mb_albumid, "") + assert self.lib.albums()[0].mb_albumid == "" def test_edit_apply_candidate(self): """Edit the album field for all items in the library, apply changes, @@ -409,13 +405,11 @@ def test_edit_apply_candidate(self): # Check that 'title' field is modified, and other fields come from # the candidate. - self.assertTrue( - all("Edited Track " in i.title for i in self.lib.items()) - ) - self.assertTrue(all("match " in i.mb_trackid for i in self.lib.items())) + assert all("Edited Track " in i.title for i in self.lib.items()) + assert all("match " in i.mb_trackid for i in self.lib.items()) # Ensure album is fetched from a candidate. - self.assertIn("albumid", self.lib.albums()[0].mb_albumid) + assert "albumid" in self.lib.albums()[0].mb_albumid def test_edit_retag_apply(self): """Import the album using a candidate, then retag and edit and apply @@ -439,13 +433,11 @@ def test_edit_retag_apply(self): # Check that 'title' field is modified, and other fields come from # the candidate. - self.assertTrue( - all("Edited Track " in i.title for i in self.lib.items()) - ) - self.assertTrue(all("match " in i.mb_trackid for i in self.lib.items())) + assert all("Edited Track " in i.title for i in self.lib.items()) + assert all("match " in i.mb_trackid for i in self.lib.items()) # Ensure album is fetched from a candidate. - self.assertIn("albumid", self.lib.albums()[0].mb_albumid) + assert "albumid" in self.lib.albums()[0].mb_albumid def test_edit_discard_candidate(self): """Edit the album field for all items in the library, discard changes, @@ -460,13 +452,11 @@ def test_edit_discard_candidate(self): # Check that 'title' field is modified, and other fields come from # the candidate. - self.assertTrue( - all("Edited Track " in i.title for i in self.lib.items()) - ) - self.assertTrue(all("match " in i.mb_trackid for i in self.lib.items())) + assert all("Edited Track " in i.title for i in self.lib.items()) + assert all("match " in i.mb_trackid for i in self.lib.items()) # Ensure album is fetched from a candidate. - self.assertIn("albumid", self.lib.albums()[0].mb_albumid) + assert "albumid" in self.lib.albums()[0].mb_albumid def test_edit_apply_candidate_singleton(self): """Edit the album field for all items in the library, apply changes, @@ -481,10 +471,8 @@ def test_edit_apply_candidate_singleton(self): # Check that 'title' field is modified, and other fields come from # the candidate. - self.assertTrue( - all("Edited Track " in i.title for i in self.lib.items()) - ) - self.assertTrue(all("match " in i.mb_trackid for i in self.lib.items())) + assert all("Edited Track " in i.title for i in self.lib.items()) + assert all("match " in i.mb_trackid for i in self.lib.items()) @_common.slow_test() @@ -511,6 +499,4 @@ def test_edit_apply_asis_singleton(self): ["title"], self.IGNORED + ["albumartist", "mb_albumartistid"], ) - self.assertTrue( - all("Edited Track" in i.title for i in self.lib.items()) - ) + assert all("Edited Track" in i.title for i in self.lib.items()) diff --git a/test/plugins/test_embedart.py b/test/plugins/test_embedart.py index 57a5b303a3..b20ff6c87e 100644 --- a/test/plugins/test_embedart.py +++ b/test/plugins/test_embedart.py @@ -20,6 +20,7 @@ from test.test_art_resize import DummyIMBackend from unittest.mock import MagicMock, patch +import pytest from mediafile import MediaFile from beets import art, config, logging, ui @@ -64,7 +65,7 @@ def test_embed_art_from_file_with_yes_input(self): self.io.addinput("y") self.run_command("embedart", "-f", self.small_artpath) mediafile = MediaFile(syspath(item.path)) - self.assertEqual(mediafile.images[0].data, self.image_data) + assert mediafile.images[0].data == self.image_data def test_embed_art_from_file_with_no_input(self): self._setup_data() @@ -74,7 +75,7 @@ def test_embed_art_from_file_with_no_input(self): self.run_command("embedart", "-f", self.small_artpath) mediafile = MediaFile(syspath(item.path)) # make sure that images array is empty (nothing embedded) - self.assertFalse(mediafile.images) + assert not mediafile.images def test_embed_art_from_file(self): self._setup_data() @@ -82,7 +83,7 @@ def test_embed_art_from_file(self): item = album.items()[0] self.run_command("embedart", "-y", "-f", self.small_artpath) mediafile = MediaFile(syspath(item.path)) - self.assertEqual(mediafile.images[0].data, self.image_data) + assert mediafile.images[0].data == self.image_data def test_embed_art_from_album(self): self._setup_data() @@ -92,7 +93,7 @@ def test_embed_art_from_album(self): album.store() self.run_command("embedart", "-y") mediafile = MediaFile(syspath(item.path)) - self.assertEqual(mediafile.images[0].data, self.image_data) + assert mediafile.images[0].data == self.image_data def test_embed_art_remove_art_file(self): self._setup_data() @@ -122,7 +123,7 @@ def test_embed_art_remove_art_file(self): def test_art_file_missing(self): self.add_album_fixture() logging.getLogger("beets.embedart").setLevel(logging.DEBUG) - with self.assertRaises(ui.UserError): + with pytest.raises(ui.UserError): self.run_command("embedart", "-y", "-f", "/doesnotexist") def test_embed_non_image_file(self): @@ -140,7 +141,7 @@ def test_embed_non_image_file(self): os.remove(syspath(tmp_path)) mediafile = MediaFile(syspath(album.items()[0].path)) - self.assertFalse(mediafile.images) # No image added. + assert not mediafile.images # No image added. @require_artresizer_compare def test_reject_different_art(self): @@ -152,13 +153,9 @@ def test_reject_different_art(self): self.run_command("embedart", "-y", "-f", self.abbey_differentpath) mediafile = MediaFile(syspath(item.path)) - self.assertEqual( - mediafile.images[0].data, - self.image_data, - "Image written is not {}".format( - displayable_path(self.abbey_artpath) - ), - ) + assert ( + mediafile.images[0].data == self.image_data + ), f"Image written is not {displayable_path(self.abbey_artpath)}" @require_artresizer_compare def test_accept_similar_art(self): @@ -170,13 +167,9 @@ def test_accept_similar_art(self): self.run_command("embedart", "-y", "-f", self.abbey_similarpath) mediafile = MediaFile(syspath(item.path)) - self.assertEqual( - mediafile.images[0].data, - self.image_data, - "Image written is not {}".format( - displayable_path(self.abbey_similarpath) - ), - ) + assert ( + mediafile.images[0].data == self.image_data + ), f"Image written is not {displayable_path(self.abbey_similarpath)}" def test_non_ascii_album_path(self): resource_path = os.path.join(_common.RSRC, b"image.mp3") @@ -209,7 +202,7 @@ def test_clear_art_with_yes_input(self): self.io.addinput("y") self.run_command("clearart") mediafile = MediaFile(syspath(item.path)) - self.assertFalse(mediafile.images) + assert not mediafile.images def test_clear_art_with_no_input(self): self._setup_data() @@ -220,7 +213,7 @@ def test_clear_art_with_no_input(self): self.io.addinput("n") self.run_command("clearart") mediafile = MediaFile(syspath(item.path)) - self.assertEqual(mediafile.images[0].data, self.image_data) + assert mediafile.images[0].data == self.image_data def test_embed_art_from_url_with_yes_input(self): self._setup_data() @@ -230,10 +223,9 @@ def test_embed_art_from_url_with_yes_input(self): self.io.addinput("y") self.run_command("embedart", "-u", "http://example.com/test.jpg") mediafile = MediaFile(syspath(item.path)) - self.assertEqual( - mediafile.images[0].data, - self.IMAGEHEADER.get("image/jpeg").ljust(32, b"\x00"), - ) + assert mediafile.images[0].data == self.IMAGEHEADER.get( + "image/jpeg" + ).ljust(32, b"\x00") def test_embed_art_from_url_png(self): self._setup_data() @@ -242,10 +234,9 @@ def test_embed_art_from_url_png(self): self.mock_response("http://example.com/test.png", "image/png") self.run_command("embedart", "-y", "-u", "http://example.com/test.png") mediafile = MediaFile(syspath(item.path)) - self.assertEqual( - mediafile.images[0].data, - self.IMAGEHEADER.get("image/png").ljust(32, b"\x00"), - ) + assert mediafile.images[0].data == self.IMAGEHEADER.get( + "image/png" + ).ljust(32, b"\x00") def test_embed_art_from_url_not_image(self): self._setup_data() @@ -254,7 +245,7 @@ def test_embed_art_from_url_not_image(self): self.mock_response("http://example.com/test.html", "text/html") self.run_command("embedart", "-y", "-u", "http://example.com/test.html") mediafile = MediaFile(syspath(item.path)) - self.assertFalse(mediafile.images) + assert not mediafile.images class DummyArtResizer(ArtResizer): @@ -308,34 +299,34 @@ def _mock_popens( def test_compare_success_similar(self, mock_extract, mock_subprocess): self._mock_popens(mock_extract, mock_subprocess, 0, "10", "err") - self.assertTrue(self._similarity(20)) + assert self._similarity(20) def test_compare_success_different(self, mock_extract, mock_subprocess): self._mock_popens(mock_extract, mock_subprocess, 0, "10", "err") - self.assertFalse(self._similarity(5)) + assert not self._similarity(5) def test_compare_status1_similar(self, mock_extract, mock_subprocess): self._mock_popens(mock_extract, mock_subprocess, 1, "out", "10") - self.assertTrue(self._similarity(20)) + assert self._similarity(20) def test_compare_status1_different(self, mock_extract, mock_subprocess): self._mock_popens(mock_extract, mock_subprocess, 1, "out", "10") - self.assertFalse(self._similarity(5)) + assert not self._similarity(5) def test_compare_failed(self, mock_extract, mock_subprocess): self._mock_popens(mock_extract, mock_subprocess, 2, "out", "10") - self.assertIsNone(self._similarity(20)) + assert self._similarity(20) is None def test_compare_parsing_error(self, mock_extract, mock_subprocess): self._mock_popens(mock_extract, mock_subprocess, 0, "foo", "bar") - self.assertIsNone(self._similarity(20)) + assert self._similarity(20) is None def test_compare_parsing_error_and_failure( self, mock_extract, mock_subprocess ): self._mock_popens(mock_extract, mock_subprocess, 1, "foo", "bar") - self.assertIsNone(self._similarity(20)) + assert self._similarity(20) is None def test_convert_failure(self, mock_extract, mock_subprocess): self._mock_popens(mock_extract, mock_subprocess, convert_status=1) - self.assertIsNone(self._similarity(20)) + assert self._similarity(20) is None diff --git a/test/plugins/test_embyupdate.py b/test/plugins/test_embyupdate.py index 5d9d37af48..8def5dca58 100644 --- a/test/plugins/test_embyupdate.py +++ b/test/plugins/test_embyupdate.py @@ -18,80 +18,73 @@ def setUp(self): } def test_api_url_only_name(self): - self.assertEqual( + assert ( embyupdate.api_url( self.config["emby"]["host"].get(), self.config["emby"]["port"].get(), "/Library/Refresh", - ), - "http://localhost:8096/Library/Refresh?format=json", + ) + == "http://localhost:8096/Library/Refresh?format=json" ) def test_api_url_http(self): - self.assertEqual( + assert ( embyupdate.api_url( "http://localhost", self.config["emby"]["port"].get(), "/Library/Refresh", - ), - "http://localhost:8096/Library/Refresh?format=json", + ) + == "http://localhost:8096/Library/Refresh?format=json" ) def test_api_url_https(self): - self.assertEqual( + assert ( embyupdate.api_url( "https://localhost", self.config["emby"]["port"].get(), "/Library/Refresh", - ), - "https://localhost:8096/Library/Refresh?format=json", + ) + == "https://localhost:8096/Library/Refresh?format=json" ) def test_password_data(self): - self.assertEqual( - embyupdate.password_data( - self.config["emby"]["username"].get(), - self.config["emby"]["password"].get(), - ), - { - "username": "username", - "password": "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8", - "passwordMd5": "5f4dcc3b5aa765d61d8327deb882cf99", - }, - ) + assert embyupdate.password_data( + self.config["emby"]["username"].get(), + self.config["emby"]["password"].get(), + ) == { + "username": "username", + "password": "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8", + "passwordMd5": "5f4dcc3b5aa765d61d8327deb882cf99", + } def test_create_header_no_token(self): - self.assertEqual( - embyupdate.create_headers("e8837bc1-ad67-520e-8cd2-f629e3155721"), - { - "x-emby-authorization": ( - "MediaBrowser " - 'UserId="e8837bc1-ad67-520e-8cd2-f629e3155721", ' - 'Client="other", ' - 'Device="beets", ' - 'DeviceId="beets", ' - 'Version="0.0.0"' - ) - }, - ) + assert embyupdate.create_headers( + "e8837bc1-ad67-520e-8cd2-f629e3155721" + ) == { + "x-emby-authorization": ( + "MediaBrowser " + 'UserId="e8837bc1-ad67-520e-8cd2-f629e3155721", ' + 'Client="other", ' + 'Device="beets", ' + 'DeviceId="beets", ' + 'Version="0.0.0"' + ) + } def test_create_header_with_token(self): - self.assertEqual( - embyupdate.create_headers( - "e8837bc1-ad67-520e-8cd2-f629e3155721", token="abc123" + assert embyupdate.create_headers( + "e8837bc1-ad67-520e-8cd2-f629e3155721", token="abc123" + ) == { + "x-emby-authorization": ( + "MediaBrowser " + 'UserId="e8837bc1-ad67-520e-8cd2-f629e3155721", ' + 'Client="other", ' + 'Device="beets", ' + 'DeviceId="beets", ' + 'Version="0.0.0"' ), - { - "x-emby-authorization": ( - "MediaBrowser " - 'UserId="e8837bc1-ad67-520e-8cd2-f629e3155721", ' - 'Client="other", ' - 'Device="beets", ' - 'DeviceId="beets", ' - 'Version="0.0.0"' - ), - "x-mediabrowser-token": "abc123", - }, - ) + "x-mediabrowser-token": "abc123", + } @responses.activate def test_get_token(self): @@ -173,9 +166,9 @@ def test_get_token(self): "passwordMd5": "5f4dcc3b5aa765d61d8327deb882cf99", } - self.assertEqual( - embyupdate.get_token("http://localhost", 8096, headers, auth_data), - "4b19180cf02748f7b95c7e8e76562fc8", + assert ( + embyupdate.get_token("http://localhost", 8096, headers, auth_data) + == "4b19180cf02748f7b95c7e8e76562fc8" ) @responses.activate @@ -230,6 +223,6 @@ def test_get_user(self): response = embyupdate.get_user("http://localhost", 8096, "username") - self.assertEqual(response[0]["Id"], "2ec276a2642e54a19b612b9418a8bd3b") + assert response[0]["Id"] == "2ec276a2642e54a19b612b9418a8bd3b" - self.assertEqual(response[0]["Name"], "username") + assert response[0]["Name"] == "username" diff --git a/test/plugins/test_export.py b/test/plugins/test_export.py index f9f28f8de8..bd1b7458d7 100644 --- a/test/plugins/test_export.py +++ b/test/plugins/test_export.py @@ -52,16 +52,16 @@ def test_json_output(self): out = self.execute_command(format_type="json", artist=item1.artist) json_data = json.loads(out)[0] for key, val in self.test_values.items(): - self.assertIn(key, json_data) - self.assertEqual(val, json_data[key]) + assert key in json_data + assert val == json_data[key] def test_jsonlines_output(self): item1 = self.create_item() out = self.execute_command(format_type="jsonlines", artist=item1.artist) json_data = json.loads(out) for key, val in self.test_values.items(): - self.assertIn(key, json_data) - self.assertEqual(val, json_data[key]) + assert key in json_data + assert val == json_data[key] def test_csv_output(self): item1 = self.create_item() @@ -70,17 +70,17 @@ def test_csv_output(self): head = re.split(",", csv_list[0]) vals = re.split(",|\r", csv_list[1]) for index, column in enumerate(head): - self.assertIsNotNone(self.test_values.get(column, None)) - self.assertEqual(vals[index], self.test_values[column]) + assert self.test_values.get(column, None) is not None + assert vals[index] == self.test_values[column] def test_xml_output(self): item1 = self.create_item() out = self.execute_command(format_type="xml", artist=item1.artist) library = ElementTree.fromstring(out) - self.assertIsInstance(library, Element) + assert isinstance(library, Element) for track in library[0]: for details in track: tag = details.tag txt = details.text - self.assertIn(tag, self.test_values, msg=tag) - self.assertEqual(self.test_values[tag], txt, msg=txt) + assert tag in self.test_values, tag + assert self.test_values[tag] == txt, txt diff --git a/test/plugins/test_fetchart.py b/test/plugins/test_fetchart.py index 86696df2d1..853820d92d 100644 --- a/test/plugins/test_fetchart.py +++ b/test/plugins/test_fetchart.py @@ -32,9 +32,9 @@ def setUp(self): self.cover_path = os.path.join(self.album.path, b"mycover.jpg") def check_cover_is_stored(self): - self.assertEqual(self.album["artpath"], self.cover_path) + assert self.album["artpath"] == self.cover_path with open(util.syspath(self.cover_path)) as f: - self.assertEqual(f.read(), "IMAGE") + assert f.read() == "IMAGE" def hide_file_windows(self): hidden_mask = 2 @@ -56,14 +56,14 @@ def test_filesystem_does_not_pick_up_folder(self): os.makedirs(os.path.join(self.album.path, b"mycover.jpg")) self.run_command("fetchart") self.album.load() - self.assertIsNone(self.album["artpath"]) + assert self.album["artpath"] is None def test_filesystem_does_not_pick_up_ignored_file(self): self.touch(b"co_ver.jpg", dir=self.album.path, content="IMAGE") self.config["ignore"] = ["*_*"] self.run_command("fetchart") self.album.load() - self.assertIsNone(self.album["artpath"]) + assert self.album["artpath"] is None def test_filesystem_picks_up_non_ignored_file(self): self.touch(b"cover.jpg", dir=self.album.path, content="IMAGE") @@ -80,7 +80,7 @@ def test_filesystem_does_not_pick_up_hidden_file(self): self.config["ignore_hidden"] = True self.run_command("fetchart") self.album.load() - self.assertIsNone(self.album["artpath"]) + assert self.album["artpath"] is None def test_filesystem_picks_up_non_hidden_file(self): self.touch(b"cover.jpg", dir=self.album.path, content="IMAGE") diff --git a/test/plugins/test_filefilter.py b/test/plugins/test_filefilter.py index d17539166f..92d19e0294 100644 --- a/test/plugins/test_filefilter.py +++ b/test/plugins/test_filefilter.py @@ -45,8 +45,8 @@ 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) + assert len(self.lib.albums()) == expected_album_count + assert {i.path for i in self.lib.items()} == expected_paths class FileFilterPluginNonSingletonTest(FileFilterPluginMixin): diff --git a/test/plugins/test_ftintitle.py b/test/plugins/test_ftintitle.py index da426e5083..f6b02b92af 100644 --- a/test/plugins/test_ftintitle.py +++ b/test/plugins/test_ftintitle.py @@ -42,38 +42,38 @@ def test_functional_drop(self): item = self._ft_add_item("/", "Alice ft Bob", "Song 1", "Alice") self.run_command("ftintitle", "-d") item.load() - self.assertEqual(item["artist"], "Alice") - self.assertEqual(item["title"], "Song 1") + assert item["artist"] == "Alice" + assert item["title"] == "Song 1" def test_functional_not_found(self): item = self._ft_add_item("/", "Alice ft Bob", "Song 1", "George") self.run_command("ftintitle", "-d") item.load() # item should be unchanged - self.assertEqual(item["artist"], "Alice ft Bob") - self.assertEqual(item["title"], "Song 1") + assert item["artist"] == "Alice ft Bob" + assert item["title"] == "Song 1" def test_functional_custom_format(self): self._ft_set_config("feat. {0}") item = self._ft_add_item("/", "Alice ft Bob", "Song 1", "Alice") self.run_command("ftintitle") item.load() - self.assertEqual(item["artist"], "Alice") - self.assertEqual(item["title"], "Song 1 feat. Bob") + assert item["artist"] == "Alice" + assert item["title"] == "Song 1 feat. Bob" self._ft_set_config("featuring {0}") item = self._ft_add_item("/", "Alice feat. Bob", "Song 1", "Alice") self.run_command("ftintitle") item.load() - self.assertEqual(item["artist"], "Alice") - self.assertEqual(item["title"], "Song 1 featuring Bob") + assert item["artist"] == "Alice" + assert item["title"] == "Song 1 featuring Bob" self._ft_set_config("with {0}") item = self._ft_add_item("/", "Alice feat Bob", "Song 1", "Alice") self.run_command("ftintitle") item.load() - self.assertEqual(item["artist"], "Alice") - self.assertEqual(item["title"], "Song 1 with Bob") + assert item["artist"] == "Alice" + assert item["title"] == "Song 1 with Bob" class FtInTitlePluginTest(unittest.TestCase): @@ -139,33 +139,33 @@ def test_find_feat_part(self): feat_part = ftintitle.find_feat_part( test_case["artist"], test_case["album_artist"] ) - self.assertEqual(feat_part, test_case["feat_part"]) + assert feat_part == test_case["feat_part"] def test_split_on_feat(self): parts = ftintitle.split_on_feat("Alice ft. Bob") - self.assertEqual(parts, ("Alice", "Bob")) + assert parts == ("Alice", "Bob") parts = ftintitle.split_on_feat("Alice feat Bob") - self.assertEqual(parts, ("Alice", "Bob")) + assert parts == ("Alice", "Bob") parts = ftintitle.split_on_feat("Alice feat. Bob") - self.assertEqual(parts, ("Alice", "Bob")) + assert parts == ("Alice", "Bob") parts = ftintitle.split_on_feat("Alice featuring Bob") - self.assertEqual(parts, ("Alice", "Bob")) + assert parts == ("Alice", "Bob") parts = ftintitle.split_on_feat("Alice & Bob") - self.assertEqual(parts, ("Alice", "Bob")) + assert parts == ("Alice", "Bob") parts = ftintitle.split_on_feat("Alice and Bob") - self.assertEqual(parts, ("Alice", "Bob")) + assert parts == ("Alice", "Bob") parts = ftintitle.split_on_feat("Alice With Bob") - self.assertEqual(parts, ("Alice", "Bob")) + assert parts == ("Alice", "Bob") parts = ftintitle.split_on_feat("Alice defeat Bob") - self.assertEqual(parts, ("Alice defeat Bob", None)) + assert parts == ("Alice defeat Bob", None) def test_contains_feat(self): - self.assertTrue(ftintitle.contains_feat("Alice ft. Bob")) - self.assertTrue(ftintitle.contains_feat("Alice feat. Bob")) - self.assertTrue(ftintitle.contains_feat("Alice feat Bob")) - self.assertTrue(ftintitle.contains_feat("Alice featuring Bob")) - self.assertTrue(ftintitle.contains_feat("Alice & Bob")) - self.assertTrue(ftintitle.contains_feat("Alice and Bob")) - self.assertTrue(ftintitle.contains_feat("Alice With Bob")) - self.assertFalse(ftintitle.contains_feat("Alice defeat Bob")) - self.assertFalse(ftintitle.contains_feat("Aliceft.Bob")) + assert ftintitle.contains_feat("Alice ft. Bob") + assert ftintitle.contains_feat("Alice feat. Bob") + assert ftintitle.contains_feat("Alice feat Bob") + assert ftintitle.contains_feat("Alice featuring Bob") + assert ftintitle.contains_feat("Alice & Bob") + assert ftintitle.contains_feat("Alice and Bob") + assert ftintitle.contains_feat("Alice With Bob") + assert not ftintitle.contains_feat("Alice defeat Bob") + assert not ftintitle.contains_feat("Aliceft.Bob") diff --git a/test/plugins/test_hook.py b/test/plugins/test_hook.py index 01abbcb1cf..c531cd8c6a 100644 --- a/test/plugins/test_hook.py +++ b/test/plugins/test_hook.py @@ -44,26 +44,24 @@ def _configure_logs(self, command: str) -> Iterator[list[str]]: def test_hook_empty_command(self): with self._configure_logs("") as logs: - self.assertIn('hook: invalid command ""', logs) + assert 'hook: invalid command ""' in logs # FIXME: fails on windows @unittest.skipIf(sys.platform == "win32", "win32") def test_hook_non_zero_exit(self): with self._configure_logs('sh -c "exit 1"') as logs: - self.assertIn( - "hook: hook for test_event exited with status 1", logs - ) + assert "hook: hook for test_event exited with status 1" in logs def test_hook_non_existent_command(self): with self._configure_logs("non-existent-command") as logs: logs = "\n".join(logs) - self.assertIn("hook: hook for test_event failed: ", logs) + assert "hook: hook for test_event failed: " in logs # The error message is different for each OS. Unfortunately the text is # different in each case, where the only shared text is the string # 'file' and substring 'Err' - self.assertIn("Err", logs) - self.assertIn("file", logs) + assert "Err" in logs + assert "file" in logs class HookCommandTest(HookTestCase): @@ -104,7 +102,7 @@ def _test_command( plugins.send(event, path=path) else: plugins.send(event) - self.assertTrue(os.path.isfile(path)) + assert os.path.isfile(path) @unittest.skipIf(sys.platform == "win32", "win32") def test_hook_no_arguments(self): diff --git a/test/plugins/test_ihate.py b/test/plugins/test_ihate.py index 92855d4166..f941d566ce 100644 --- a/test/plugins/test_ihate.py +++ b/test/plugins/test_ihate.py @@ -16,30 +16,30 @@ def test_hate(self): task = importer.SingletonImportTask(None, test_item) # Empty query should let it pass. - self.assertFalse(IHatePlugin.do_i_hate_this(task, match_pattern)) + assert not IHatePlugin.do_i_hate_this(task, match_pattern) # 1 query match. match_pattern = ["artist:bad_artist", "artist:TestArtist"] - self.assertTrue(IHatePlugin.do_i_hate_this(task, match_pattern)) + assert IHatePlugin.do_i_hate_this(task, match_pattern) # 2 query matches, either should trigger. match_pattern = ["album:test", "artist:testartist"] - self.assertTrue(IHatePlugin.do_i_hate_this(task, match_pattern)) + assert IHatePlugin.do_i_hate_this(task, match_pattern) # Query is blocked by AND clause. match_pattern = ["album:notthis genre:testgenre"] - self.assertFalse(IHatePlugin.do_i_hate_this(task, match_pattern)) + assert not IHatePlugin.do_i_hate_this(task, match_pattern) # Both queries are blocked by AND clause with unmatched condition. match_pattern = [ "album:notthis genre:testgenre", "artist:testartist album:notthis", ] - self.assertFalse(IHatePlugin.do_i_hate_this(task, match_pattern)) + assert not IHatePlugin.do_i_hate_this(task, match_pattern) # Only one query should fire. match_pattern = [ "album:testalbum genre:testgenre", "artist:testartist album:notthis", ] - self.assertTrue(IHatePlugin.do_i_hate_this(task, match_pattern)) + assert IHatePlugin.do_i_hate_this(task, match_pattern) diff --git a/test/plugins/test_importadded.py b/test/plugins/test_importadded.py index b055e16cc0..6af4b0a63c 100644 --- a/test/plugins/test_importadded.py +++ b/test/plugins/test_importadded.py @@ -17,6 +17,8 @@ import os +import pytest + from beets import importer from beets.test.helper import AutotagStub, ImportTestCase, PluginMixin from beets.util import displayable_path, syspath @@ -74,14 +76,14 @@ def find_media_file(self, item): def assertEqualTimes(self, first, second, msg=None): # noqa """For comparing file modification times at a sufficient precision""" - self.assertAlmostEqual(first, second, places=4, msg=msg) + assert first == pytest.approx(second, rel=1e-4), msg def assertAlbumImport(self): # noqa self.importer.run() album = self.lib.albums().get() - self.assertEqual(album.added, self.min_mtime) + assert album.added == self.min_mtime for item in album.items(): - self.assertEqual(item.added, self.min_mtime) + assert item.added == self.min_mtime def test_import_album_with_added_dates(self): self.assertAlbumImport() @@ -97,7 +99,7 @@ def test_import_album_with_preserved_mtimes(self): self.config["importadded"]["preserve_mtimes"] = True self.importer.run() album = self.lib.albums().get() - self.assertEqual(album.added, self.min_mtime) + assert album.added == self.min_mtime for item in album.items(): self.assertEqualTimes(item.added, self.min_mtime) mediafile_mtime = os.path.getmtime(self.find_media_file(item).path) diff --git a/test/plugins/test_importfeeds.py b/test/plugins/test_importfeeds.py index 2b640ca377..5f1f915ad9 100644 --- a/test/plugins/test_importfeeds.py +++ b/test/plugins/test_importfeeds.py @@ -27,9 +27,9 @@ def test_multi_format_album_playlist(self): playlist_path = os.path.join( self.feeds_dir, os.listdir(self.feeds_dir)[0] ) - self.assertTrue(playlist_path.endswith("album_name.m3u")) + assert playlist_path.endswith("album_name.m3u") with open(playlist_path) as playlist: - self.assertIn(item_path, playlist.read()) + assert item_path in playlist.read() def test_playlist_in_subdir(self): config["importfeeds"]["formats"] = "m3u" @@ -47,8 +47,8 @@ def test_playlist_in_subdir(self): self.feeds_dir, config["importfeeds"]["m3u_name"].get() ) playlist_subdir = os.path.dirname(playlist) - self.assertTrue(os.path.isdir(playlist_subdir)) - self.assertTrue(os.path.isfile(playlist)) + assert os.path.isdir(playlist_subdir) + assert os.path.isfile(playlist) def test_playlist_per_session(self): config["importfeeds"]["formats"] = "m3u_session" @@ -63,6 +63,6 @@ def test_playlist_per_session(self): self.importfeeds.album_imported(self.lib, album) date = datetime.datetime.now().strftime("%Y%m%d_%Hh%M") playlist = os.path.join(self.feeds_dir, f"imports_{date}.m3u") - self.assertTrue(os.path.isfile(playlist)) + assert os.path.isfile(playlist) with open(playlist) as playlist_contents: - self.assertIn(item_path, playlist_contents.read()) + assert item_path in playlist_contents.read() diff --git a/test/plugins/test_info.py b/test/plugins/test_info.py index 102aceb83a..c1b3fc941a 100644 --- a/test/plugins/test_info.py +++ b/test/plugins/test_info.py @@ -33,11 +33,11 @@ def test_path(self): mediafile.save() out = self.run_with_output("info", path) - self.assertIn(displayable_path(path), out) - self.assertIn("albumartist: AAA", out) - self.assertIn("disctitle: DDD", out) - self.assertIn("genres: a; b; c", out) - self.assertNotIn("composer:", out) + assert displayable_path(path) in out + assert "albumartist: AAA" in out + assert "disctitle: DDD" in out + assert "genres: a; b; c" in out + assert "composer:" not in out def test_item_query(self): item1, item2 = self.add_item_fixtures(count=2) @@ -47,10 +47,10 @@ def test_item_query(self): item1.store() out = self.run_with_output("info", "album:yyyy") - self.assertIn(displayable_path(item1.path), out) - self.assertIn("album: xxxx", out) + assert displayable_path(item1.path) in out + assert "album: xxxx" in out - self.assertNotIn(displayable_path(item2.path), out) + assert displayable_path(item2.path) not in out def test_item_library_query(self): (item,) = self.add_item_fixtures() @@ -58,8 +58,8 @@ def test_item_library_query(self): item.store() out = self.run_with_output("info", "--library", "album:xxxx") - self.assertIn(displayable_path(item.path), out) - self.assertIn("album: xxxx", out) + assert displayable_path(item.path) in out + assert "album: xxxx" in out def test_collect_item_and_path(self): path = self.create_mediafile_fixture() @@ -76,9 +76,9 @@ def test_collect_item_and_path(self): mediafile.save() out = self.run_with_output("info", "--summarize", "album:AAA", path) - self.assertIn("album: AAA", out) - self.assertIn("tracktotal: 5", out) - self.assertIn("title: [various]", out) + assert "album: AAA" in out + assert "tracktotal: 5" in out + assert "title: [various]" in out def test_collect_item_and_path_with_multi_values(self): path = self.create_mediafile_fixture() @@ -101,11 +101,11 @@ def test_collect_item_and_path_with_multi_values(self): mediafile.save() out = self.run_with_output("info", "--summarize", "album:AAA", path) - self.assertIn("album: AAA", out) - self.assertIn("tracktotal: 5", out) - self.assertIn("title: [various]", out) - self.assertIn("albumartists: [various]", out) - self.assertIn("artists: Artist A; Artist Z", out) + assert "album: AAA" in out + assert "tracktotal: 5" in out + assert "title: [various]" in out + assert "albumartists: [various]" in out + assert "artists: Artist A; Artist Z" in out def test_custom_format(self): self.add_item_fixtures() @@ -115,4 +115,4 @@ def test_custom_format(self): "--format", "$track. $title - $artist ($length)", ) - self.assertEqual("02. tïtle 0 - the artist (0:01)\n", out) + assert "02. tïtle 0 - the artist (0:01)\n" == out diff --git a/test/plugins/test_ipfs.py b/test/plugins/test_ipfs.py index 2640ef98fb..34c31d7772 100644 --- a/test/plugins/test_ipfs.py +++ b/test/plugins/test_ipfs.py @@ -30,7 +30,7 @@ def test_stored_hashes(self): ipfs = IPFSPlugin() added_albums = ipfs.ipfs_added_albums(self.lib, self.lib.path) added_album = added_albums.get_album(1) - self.assertEqual(added_album.ipfs, test_album.ipfs) + assert added_album.ipfs == test_album.ipfs found = False want_item = test_album.items()[2] for check_item in added_album.items(): @@ -41,15 +41,16 @@ def test_stored_hashes(self): ) want_path = "/ipfs/{}/{}".format(test_album.ipfs, ipfs_item) want_path = bytestring_path(want_path) - self.assertEqual(check_item.path, want_path) - self.assertEqual( - check_item.get("ipfs", with_album=False), want_item.ipfs + assert check_item.path == want_path + assert ( + check_item.get("ipfs", with_album=False) + == want_item.ipfs ) - self.assertEqual(check_item.title, want_item.title) + assert check_item.title == want_item.title found = True except AttributeError: pass - self.assertTrue(found) + assert found def mk_test_album(self): items = [_common.item() for _ in range(3)] diff --git a/test/plugins/test_keyfinder.py b/test/plugins/test_keyfinder.py index ae82438457..15314e1419 100644 --- a/test/plugins/test_keyfinder.py +++ b/test/plugins/test_keyfinder.py @@ -32,7 +32,7 @@ def test_add_key(self, command_output): self.run_command("keyfinder") item.load() - self.assertEqual(item["initial_key"], "C#m") + assert item["initial_key"] == "C#m" command_output.assert_called_with( ["KeyFinder", "-f", util.syspath(item.path)] ) @@ -42,7 +42,7 @@ def test_add_key_on_import(self, command_output): self.run_asis_importer() item = self.lib.items().get() - self.assertEqual(item["initial_key"], "C#m") + assert item["initial_key"] == "C#m" def test_force_overwrite(self, command_output): self.config["keyfinder"]["overwrite"] = True @@ -54,7 +54,7 @@ def test_force_overwrite(self, command_output): self.run_command("keyfinder") item.load() - self.assertEqual(item["initial_key"], "C#m") + assert item["initial_key"] == "C#m" def test_do_not_overwrite(self, command_output): item = Item(path="/file", initial_key="F") @@ -64,7 +64,7 @@ def test_do_not_overwrite(self, command_output): self.run_command("keyfinder") item.load() - self.assertEqual(item["initial_key"], "F") + assert item["initial_key"] == "F" def test_no_key(self, command_output): item = Item(path="/file") @@ -74,4 +74,4 @@ def test_no_key(self, command_output): self.run_command("keyfinder") item.load() - self.assertIsNone(item["initial_key"]) + assert item["initial_key"] is None diff --git a/test/plugins/test_lastgenre.py b/test/plugins/test_lastgenre.py index 9efcf5fc41..17156453ec 100644 --- a/test/plugins/test_lastgenre.py +++ b/test/plugins/test_lastgenre.py @@ -14,7 +14,6 @@ """Tests for the 'lastgenre' plugin.""" - from unittest.mock import Mock from beets import config @@ -45,50 +44,46 @@ def _setup_config( def test_default(self): """Fetch genres with whitelist and c14n deactivated""" self._setup_config() - self.assertEqual( - self.plugin._resolve_genres(["delta blues"]), "Delta Blues" - ) + assert self.plugin._resolve_genres(["delta blues"]) == "Delta Blues" def test_c14n_only(self): """Default c14n tree funnels up to most common genre except for *wrong* genres that stay unchanged. """ self._setup_config(canonical=True, count=99) - self.assertEqual(self.plugin._resolve_genres(["delta blues"]), "Blues") - self.assertEqual( - self.plugin._resolve_genres(["iota blues"]), "Iota Blues" - ) + assert self.plugin._resolve_genres(["delta blues"]) == "Blues" + assert self.plugin._resolve_genres(["iota blues"]) == "Iota Blues" def test_whitelist_only(self): """Default whitelist rejects *wrong* (non existing) genres.""" self._setup_config(whitelist=True) - self.assertEqual(self.plugin._resolve_genres(["iota blues"]), "") + assert self.plugin._resolve_genres(["iota blues"]) == "" def test_whitelist_c14n(self): """Default whitelist and c14n both activated result in all parents genres being selected (from specific to common). """ self._setup_config(canonical=True, whitelist=True, count=99) - self.assertEqual( - self.plugin._resolve_genres(["delta blues"]), "Delta Blues, Blues" + assert ( + self.plugin._resolve_genres(["delta blues"]) == "Delta Blues, Blues" ) def test_whitelist_custom(self): """Keep only genres that are in the whitelist.""" self._setup_config(whitelist={"blues", "rock", "jazz"}, count=2) - self.assertEqual(self.plugin._resolve_genres(["pop", "blues"]), "Blues") + assert self.plugin._resolve_genres(["pop", "blues"]) == "Blues" self._setup_config(canonical="", whitelist={"rock"}) - self.assertEqual(self.plugin._resolve_genres(["delta blues"]), "") + assert self.plugin._resolve_genres(["delta blues"]) == "" def test_count(self): """Keep the n first genres, as we expect them to be sorted from more to less popular. """ self._setup_config(whitelist={"blues", "rock", "jazz"}, count=2) - self.assertEqual( - self.plugin._resolve_genres(["jazz", "pop", "rock", "blues"]), - "Jazz, Rock", + assert ( + self.plugin._resolve_genres(["jazz", "pop", "rock", "blues"]) + == "Jazz, Rock" ) def test_count_c14n(self): @@ -98,53 +93,51 @@ def test_count_c14n(self): ) # thanks to c14n, 'blues' superseeds 'country blues' and takes the # second slot - self.assertEqual( + assert ( self.plugin._resolve_genres( ["jazz", "pop", "country blues", "rock"] - ), - "Jazz, Blues", + ) + == "Jazz, Blues" ) def test_c14n_whitelist(self): """Genres first pass through c14n and are then filtered""" self._setup_config(canonical=True, whitelist={"rock"}) - self.assertEqual(self.plugin._resolve_genres(["delta blues"]), "") + assert self.plugin._resolve_genres(["delta blues"]) == "" def test_empty_string_enables_canonical(self): """For backwards compatibility, setting the `canonical` option to the empty string enables it using the default tree. """ self._setup_config(canonical="", count=99) - self.assertEqual(self.plugin._resolve_genres(["delta blues"]), "Blues") + assert self.plugin._resolve_genres(["delta blues"]) == "Blues" def test_empty_string_enables_whitelist(self): """Again for backwards compatibility, setting the `whitelist` option to the empty string enables the default set of genres. """ self._setup_config(whitelist="") - self.assertEqual(self.plugin._resolve_genres(["iota blues"]), "") + assert self.plugin._resolve_genres(["iota blues"]) == "" def test_prefer_specific_loads_tree(self): """When prefer_specific is enabled but canonical is not the tree still has to be loaded. """ self._setup_config(prefer_specific=True, canonical=False) - self.assertNotEqual(self.plugin.c14n_branches, []) + assert self.plugin.c14n_branches != [] def test_prefer_specific_without_canonical(self): """Prefer_specific works without canonical.""" self._setup_config(prefer_specific=True, canonical=False, count=4) - self.assertEqual( - self.plugin._resolve_genres(["math rock", "post-rock"]), - "Post-Rock, Math Rock", + assert ( + self.plugin._resolve_genres(["math rock", "post-rock"]) + == "Post-Rock, Math Rock" ) def test_no_duplicate(self): """Remove duplicated genres.""" self._setup_config(count=99) - self.assertEqual( - self.plugin._resolve_genres(["blues", "blues"]), "Blues" - ) + assert self.plugin._resolve_genres(["blues", "blues"]) == "Blues" def test_tags_for(self): class MockPylastElem: @@ -166,9 +159,9 @@ def get_top_tags(self): plugin = lastgenre.LastGenrePlugin() res = plugin._tags_for(MockPylastObj()) - self.assertEqual(res, ["pop", "rap"]) + assert res == ["pop", "rap"] res = plugin._tags_for(MockPylastObj(), min_weight=50) - self.assertEqual(res, ["pop"]) + assert res == ["pop"] def test_get_genre(self): mock_genres = {"track": "1", "album": "2", "artist": "3"} @@ -192,40 +185,36 @@ def mock_fetch_artist_genre(self, obj): config["lastgenre"] = {"force": False} res = self.plugin._get_genre(item) - self.assertEqual(res, (item.genre, "keep")) + assert res == (item.genre, "keep") config["lastgenre"] = {"force": True, "source": "track"} res = self.plugin._get_genre(item) - self.assertEqual(res, (mock_genres["track"], "track")) + assert res == (mock_genres["track"], "track") config["lastgenre"] = {"source": "album"} res = self.plugin._get_genre(item) - self.assertEqual(res, (mock_genres["album"], "album")) + assert res == (mock_genres["album"], "album") config["lastgenre"] = {"source": "artist"} res = self.plugin._get_genre(item) - self.assertEqual(res, (mock_genres["artist"], "artist")) + assert res == (mock_genres["artist"], "artist") mock_genres["artist"] = None res = self.plugin._get_genre(item) - self.assertEqual(res, (item.genre, "original")) + assert res == (item.genre, "original") config["lastgenre"] = {"fallback": "rap"} item.genre = None res = self.plugin._get_genre(item) - self.assertEqual( - res, (config["lastgenre"]["fallback"].get(), "fallback") - ) + assert res == (config["lastgenre"]["fallback"].get(), "fallback") def test_sort_by_depth(self): self._setup_config(canonical=True) # Normal case. tags = ("electronic", "ambient", "post-rock", "downtempo") res = self.plugin._sort_by_depth(tags) - self.assertEqual( - res, ["post-rock", "downtempo", "ambient", "electronic"] - ) + assert res == ["post-rock", "downtempo", "ambient", "electronic"] # Non-canonical tag ('chillout') present. tags = ("electronic", "ambient", "chillout") res = self.plugin._sort_by_depth(tags) - self.assertEqual(res, ["ambient", "electronic"]) + assert res == ["ambient", "electronic"] diff --git a/test/plugins/test_limit.py b/test/plugins/test_limit.py index 5377cd43b8..9f372992bd 100644 --- a/test/plugins/test_limit.py +++ b/test/plugins/test_limit.py @@ -49,47 +49,47 @@ def setUp(self): def test_no_limit(self): """Returns all when there is no limit or filter.""" result = self.run_with_output("lslimit") - self.assertEqual(result.count("\n"), self.num_test_items) + assert result.count("\n") == self.num_test_items def test_lslimit_head(self): """Returns the expected number with `lslimit --head`.""" result = self.run_with_output("lslimit", "--head", str(self.num_limit)) - self.assertEqual(result.count("\n"), self.num_limit) + assert result.count("\n") == self.num_limit def test_lslimit_tail(self): """Returns the expected number with `lslimit --tail`.""" result = self.run_with_output("lslimit", "--tail", str(self.num_limit)) - self.assertEqual(result.count("\n"), self.num_limit) + assert result.count("\n") == self.num_limit def test_lslimit_head_invariant(self): """Returns the expected number with `lslimit --head` and a filter.""" result = self.run_with_output( "lslimit", "--head", str(self.num_limit), self.track_tail_range ) - self.assertEqual(result.count("\n"), self.num_limit) + assert result.count("\n") == self.num_limit def test_lslimit_tail_invariant(self): """Returns the expected number with `lslimit --tail` and a filter.""" result = self.run_with_output( "lslimit", "--tail", str(self.num_limit), self.track_head_range ) - self.assertEqual(result.count("\n"), self.num_limit) + assert result.count("\n") == self.num_limit def test_prefix(self): """Returns the expected number with the query prefix.""" result = self.lib.items(self.num_limit_prefix) - self.assertEqual(len(result), self.num_limit) + assert len(result) == self.num_limit def test_prefix_when_correctly_ordered(self): """Returns the expected number with the query prefix and filter when the prefix portion (correctly) appears last.""" correct_order = self.track_tail_range + " " + self.num_limit_prefix result = self.lib.items(correct_order) - self.assertEqual(len(result), self.num_limit) + assert len(result) == self.num_limit def test_prefix_when_incorrectly_ordred(self): """Returns no results with the query prefix and filter when the prefix portion (incorrectly) appears first.""" incorrect_order = self.num_limit_prefix + " " + self.track_tail_range result = self.lib.items(incorrect_order) - self.assertEqual(len(result), 0) + assert len(result) == 0 diff --git a/test/plugins/test_lyrics.py b/test/plugins/test_lyrics.py index 0066235352..7cb081fc42 100644 --- a/test/plugins/test_lyrics.py +++ b/test/plugins/test_lyrics.py @@ -45,116 +45,106 @@ def setUp(self): def test_search_artist(self): item = Item(artist="Alice ft. Bob", title="song") - self.assertIn(("Alice ft. Bob", ["song"]), lyrics.search_pairs(item)) - self.assertIn(("Alice", ["song"]), lyrics.search_pairs(item)) + assert ("Alice ft. Bob", ["song"]) in lyrics.search_pairs(item) + assert ("Alice", ["song"]) in lyrics.search_pairs(item) item = Item(artist="Alice feat Bob", title="song") - self.assertIn(("Alice feat Bob", ["song"]), lyrics.search_pairs(item)) - self.assertIn(("Alice", ["song"]), lyrics.search_pairs(item)) + assert ("Alice feat Bob", ["song"]) in lyrics.search_pairs(item) + assert ("Alice", ["song"]) in lyrics.search_pairs(item) item = Item(artist="Alice feat. Bob", title="song") - self.assertIn(("Alice feat. Bob", ["song"]), lyrics.search_pairs(item)) - self.assertIn(("Alice", ["song"]), lyrics.search_pairs(item)) + assert ("Alice feat. Bob", ["song"]) in lyrics.search_pairs(item) + assert ("Alice", ["song"]) in lyrics.search_pairs(item) item = Item(artist="Alice feats Bob", title="song") - self.assertIn(("Alice feats Bob", ["song"]), lyrics.search_pairs(item)) - self.assertNotIn(("Alice", ["song"]), lyrics.search_pairs(item)) + assert ("Alice feats Bob", ["song"]) in lyrics.search_pairs(item) + assert ("Alice", ["song"]) not in lyrics.search_pairs(item) item = Item(artist="Alice featuring Bob", title="song") - self.assertIn( - ("Alice featuring Bob", ["song"]), lyrics.search_pairs(item) - ) - self.assertIn(("Alice", ["song"]), lyrics.search_pairs(item)) + assert ("Alice featuring Bob", ["song"]) in lyrics.search_pairs(item) + assert ("Alice", ["song"]) in lyrics.search_pairs(item) item = Item(artist="Alice & Bob", title="song") - self.assertIn(("Alice & Bob", ["song"]), lyrics.search_pairs(item)) - self.assertIn(("Alice", ["song"]), lyrics.search_pairs(item)) + assert ("Alice & Bob", ["song"]) in lyrics.search_pairs(item) + assert ("Alice", ["song"]) in lyrics.search_pairs(item) item = Item(artist="Alice and Bob", title="song") - self.assertIn(("Alice and Bob", ["song"]), lyrics.search_pairs(item)) - self.assertIn(("Alice", ["song"]), lyrics.search_pairs(item)) + assert ("Alice and Bob", ["song"]) in lyrics.search_pairs(item) + assert ("Alice", ["song"]) in lyrics.search_pairs(item) item = Item(artist="Alice and Bob", title="song") - self.assertEqual( - ("Alice and Bob", ["song"]), list(lyrics.search_pairs(item))[0] - ) + assert ("Alice and Bob", ["song"]) == list(lyrics.search_pairs(item))[0] def test_search_artist_sort(self): item = Item(artist="CHVRCHΞS", title="song", artist_sort="CHVRCHES") - self.assertIn(("CHVRCHΞS", ["song"]), lyrics.search_pairs(item)) - self.assertIn(("CHVRCHES", ["song"]), lyrics.search_pairs(item)) + assert ("CHVRCHΞS", ["song"]) in lyrics.search_pairs(item) + assert ("CHVRCHES", ["song"]) in lyrics.search_pairs(item) # Make sure that the original artist name is still the first entry - self.assertEqual( - ("CHVRCHΞS", ["song"]), list(lyrics.search_pairs(item))[0] - ) + assert ("CHVRCHΞS", ["song"]) == list(lyrics.search_pairs(item))[0] item = Item( artist="横山克", title="song", artist_sort="Masaru Yokoyama" ) - self.assertIn(("横山克", ["song"]), lyrics.search_pairs(item)) - self.assertIn(("Masaru Yokoyama", ["song"]), lyrics.search_pairs(item)) + assert ("横山克", ["song"]) in lyrics.search_pairs(item) + assert ("Masaru Yokoyama", ["song"]) in lyrics.search_pairs(item) # Make sure that the original artist name is still the first entry - self.assertEqual( - ("横山克", ["song"]), list(lyrics.search_pairs(item))[0] - ) + assert ("横山克", ["song"]) == list(lyrics.search_pairs(item))[0] def test_search_pairs_multi_titles(self): item = Item(title="1 / 2", artist="A") - self.assertIn(("A", ["1 / 2"]), lyrics.search_pairs(item)) - self.assertIn(("A", ["1", "2"]), lyrics.search_pairs(item)) + assert ("A", ["1 / 2"]) in lyrics.search_pairs(item) + assert ("A", ["1", "2"]) in lyrics.search_pairs(item) item = Item(title="1/2", artist="A") - self.assertIn(("A", ["1/2"]), lyrics.search_pairs(item)) - self.assertIn(("A", ["1", "2"]), lyrics.search_pairs(item)) + assert ("A", ["1/2"]) in lyrics.search_pairs(item) + assert ("A", ["1", "2"]) in lyrics.search_pairs(item) def test_search_pairs_titles(self): item = Item(title="Song (live)", artist="A") - self.assertIn(("A", ["Song"]), lyrics.search_pairs(item)) - self.assertIn(("A", ["Song (live)"]), lyrics.search_pairs(item)) + assert ("A", ["Song"]) in lyrics.search_pairs(item) + assert ("A", ["Song (live)"]) in lyrics.search_pairs(item) item = Item(title="Song (live) (new)", artist="A") - self.assertIn(("A", ["Song"]), lyrics.search_pairs(item)) - self.assertIn(("A", ["Song (live) (new)"]), lyrics.search_pairs(item)) + assert ("A", ["Song"]) in lyrics.search_pairs(item) + assert ("A", ["Song (live) (new)"]) in lyrics.search_pairs(item) item = Item(title="Song (live (new))", artist="A") - self.assertIn(("A", ["Song"]), lyrics.search_pairs(item)) - self.assertIn(("A", ["Song (live (new))"]), lyrics.search_pairs(item)) + assert ("A", ["Song"]) in lyrics.search_pairs(item) + assert ("A", ["Song (live (new))"]) in lyrics.search_pairs(item) item = Item(title="Song ft. B", artist="A") - self.assertIn(("A", ["Song"]), lyrics.search_pairs(item)) - self.assertIn(("A", ["Song ft. B"]), lyrics.search_pairs(item)) + assert ("A", ["Song"]) in lyrics.search_pairs(item) + assert ("A", ["Song ft. B"]) in lyrics.search_pairs(item) item = Item(title="Song featuring B", artist="A") - self.assertIn(("A", ["Song"]), lyrics.search_pairs(item)) - self.assertIn(("A", ["Song featuring B"]), lyrics.search_pairs(item)) + assert ("A", ["Song"]) in lyrics.search_pairs(item) + assert ("A", ["Song featuring B"]) in lyrics.search_pairs(item) item = Item(title="Song and B", artist="A") - self.assertNotIn(("A", ["Song"]), lyrics.search_pairs(item)) - self.assertIn(("A", ["Song and B"]), lyrics.search_pairs(item)) + assert ("A", ["Song and B"]) in lyrics.search_pairs(item) + assert ("A", ["Song"]) not in lyrics.search_pairs(item) item = Item(title="Song: B", artist="A") - self.assertIn(("A", ["Song"]), lyrics.search_pairs(item)) - self.assertIn(("A", ["Song: B"]), lyrics.search_pairs(item)) + assert ("A", ["Song"]) in lyrics.search_pairs(item) + assert ("A", ["Song: B"]) in lyrics.search_pairs(item) def test_remove_credits(self): - self.assertEqual( + assert ( lyrics.remove_credits( """It's close to midnight Lyrics brought by example.com""" - ), - "It's close to midnight", - ) - self.assertEqual( - lyrics.remove_credits("""Lyrics brought by example.com"""), "" + ) + == "It's close to midnight" ) + assert lyrics.remove_credits("""Lyrics brought by example.com""") == "" # don't remove 2nd verse for the only reason it contains 'lyrics' word text = """Look at all the shit that i done bought her See lyrics ain't nothin if the beat aint crackin""" - self.assertEqual(lyrics.remove_credits(text), text) + assert lyrics.remove_credits(text) == text def test_is_lyrics(self): texts = ["LyricsMania.com - Copyright (c) 2013 - All Rights Reserved"] @@ -163,11 +153,11 @@ def test_is_lyrics(self): of mywickedsongtext brand""" ] for t in texts: - self.assertFalse(google.is_lyrics(t)) + assert not google.is_lyrics(t) def test_slugify(self): text = "http://site.com/\xe7afe-au_lait(boisson)" - self.assertEqual(google.slugify(text), "http://site.com/cafe_au_lait") + assert google.slugify(text) == "http://site.com/cafe_au_lait" def test_scrape_strip_cruft(self): text = """ @@ -176,26 +166,22 @@ def test_scrape_strip_cruft(self): two !

four""" - self.assertEqual( - lyrics._scrape_strip_cruft(text, True), "one\ntwo !\n\nfour" - ) + assert lyrics._scrape_strip_cruft(text, True) == "one\ntwo !\n\nfour" def test_scrape_strip_scripts(self): text = """foobaz""" - self.assertEqual(lyrics._scrape_strip_cruft(text, True), "foobaz") + assert lyrics._scrape_strip_cruft(text, True) == "foobaz" def test_scrape_strip_tag_in_comment(self): text = """fooqux""" - self.assertEqual(lyrics._scrape_strip_cruft(text, True), "fooqux") + assert lyrics._scrape_strip_cruft(text, True) == "fooqux" def test_scrape_merge_paragraphs(self): text = "one

two

three" - self.assertEqual( - lyrics._scrape_merge_paragraphs(text), "one\ntwo\nthree" - ) + assert lyrics._scrape_merge_paragraphs(text) == "one\ntwo\nthree" def test_missing_lyrics(self): - self.assertFalse(google.is_lyrics(LYRICS_TEXTS["missing_texts"])) + assert not google.is_lyrics(LYRICS_TEXTS["missing_texts"]) def url_to_filename(url): @@ -379,7 +365,7 @@ def test_google_sources_ok(self): for s in sources: url = s["url"] + s["path"] res = lyrics.scrape_lyrics_from_html(raw_backend.fetch_url(url)) - self.assertTrue(google.is_lyrics(res), url) + assert google.is_lyrics(res), url self.assertLyricsContentOk(s["title"], res, url) @@ -403,7 +389,7 @@ def test_mocked_source_ok(self): """Test that lyrics of the mocked page are correctly scraped""" url = self.source["url"] + self.source["path"] res = lyrics.scrape_lyrics_from_html(raw_backend.fetch_url(url)) - self.assertTrue(google.is_lyrics(res), url) + assert google.is_lyrics(res), url self.assertLyricsContentOk(self.source["title"], res, url) @patch.object(lyrics.Backend, "fetch_url", MockFetchUrl()) @@ -419,12 +405,9 @@ def test_is_page_candidate_exact_match(self): soup = BeautifulSoup( html, "html.parser", parse_only=SoupStrainer("title") ) - self.assertTrue( - google.is_page_candidate( - url, soup.title.string, s["title"], s["artist"] - ), - url, - ) + assert google.is_page_candidate( + url, soup.title.string, s["title"], s["artist"] + ), url def test_is_page_candidate_fuzzy_match(self): """Test matching html page title with song infos -- when song infos are @@ -435,16 +418,14 @@ def test_is_page_candidate_fuzzy_match(self): url_title = "example.com | Beats song by John doe" # very small diffs (typo) are ok eg 'beats' vs 'beets' with same artist - self.assertTrue( - google.is_page_candidate(url, url_title, s["title"], s["artist"]), - url, - ) + assert google.is_page_candidate( + url, url_title, s["title"], s["artist"] + ), url # reject different title url_title = "example.com | seets bong lyrics by John doe" - self.assertFalse( - google.is_page_candidate(url, url_title, s["title"], s["artist"]), - url, - ) + assert not google.is_page_candidate( + url, url_title, s["title"], s["artist"] + ), url def test_is_page_candidate_special_chars(self): """Ensure that `is_page_candidate` doesn't crash when the artist @@ -486,23 +467,23 @@ def test_no_lyrics_div(self): # expected return value None url = "https://genius.com/sample" mock = MockFetchUrl() - self.assertIsNone(genius._scrape_lyrics_from_html(mock(url))) + assert genius._scrape_lyrics_from_html(mock(url)) is None def test_good_lyrics(self): """Ensure we are able to scrape a page with lyrics""" url = "https://genius.com/Ttng-chinchilla-lyrics" mock = MockFetchUrl() lyrics = genius._scrape_lyrics_from_html(mock(url)) - self.assertIsNotNone(lyrics) - self.assertEqual(lyrics.count("\n"), 28) + assert lyrics is not None + assert lyrics.count("\n") == 28 def test_good_lyrics_multiple_divs(self): """Ensure we are able to scrape a page with lyrics""" url = "https://genius.com/2pac-all-eyez-on-me-lyrics" mock = MockFetchUrl() lyrics = genius._scrape_lyrics_from_html(mock(url)) - self.assertIsNotNone(lyrics) - self.assertEqual(lyrics.count("\n"), 133) + assert lyrics is not None + assert lyrics.count("\n") == 133 # TODO: find an example of a lyrics page with multiple divs and test it @@ -545,21 +526,21 @@ def test_json(self, mock_fetch_url, mock_scrape): ) as mock_json: # genius uses zero-width-spaces (\u200B) for lowercase # artists so we make sure we can match those - self.assertIsNotNone(genius.fetch("blackbear", "Idfc")) + assert genius.fetch("blackbear", "Idfc") is not None mock_fetch_url.assert_called_once_with("blackbear_url") mock_scrape.assert_called_once_with(True) # genius uses the hyphen minus (\u002D) as their dash - self.assertIsNotNone(genius.fetch("El-p", "Idfc")) + assert genius.fetch("El-p", "Idfc") is not None mock_fetch_url.assert_called_with("El-p_url") mock_scrape.assert_called_with(True) # test no matching artist - self.assertIsNone(genius.fetch("doesntexist", "none")) + assert genius.fetch("doesntexist", "none") is None # test invalid json mock_json.return_value = None - self.assertIsNone(genius.fetch("blackbear", "Idfc")) + assert genius.fetch("blackbear", "Idfc") is None # TODO: add integration test hitting real api @@ -589,8 +570,9 @@ def test_good_lyrics(self): """Ensure we are able to scrape a page with lyrics""" url = "https://www.tekstowo.pl/piosenka,24kgoldn,city_of_angels_1.html" mock = MockFetchUrl() - self.assertIsNotNone( + assert ( tekstowo.extract_lyrics(mock(url), "24kGoldn", "City of Angels") + is not None ) def test_no_lyrics(self): @@ -602,13 +584,13 @@ def test_no_lyrics(self): "beethoven_piano_sonata_17_tempest_the_3rd_movement.html" ) mock = MockFetchUrl() - self.assertEqual( + assert ( tekstowo.extract_lyrics( mock(url), "Beethoven", "Beethoven Piano Sonata 17" "Tempest The 3rd Movement", - ), - None, + ) + is None ) def test_song_no_match(self): @@ -620,11 +602,11 @@ def test_song_no_match(self): ",black_eyed_susan.html" ) mock = MockFetchUrl() - self.assertEqual( + assert ( tekstowo.extract_lyrics( mock(url), "Kelly Bailey", "Black Mesa Inbound" - ), - None, + ) + is None ) @@ -643,10 +625,10 @@ def test_multiple_results(self): ",tytul,lucid+dreams.html" ) mock = MockFetchUrl() - self.assertEqual( - tekstowo.parse_search_results(mock(url)), - "http://www.tekstowo.pl/piosenka,juice_wrld," - "lucid_dreams__remix__ft__lil_uzi_vert.html", + assert ( + tekstowo.parse_search_results(mock(url)) + == "http://www.tekstowo.pl/piosenka,juice_wrld," + "lucid_dreams__remix__ft__lil_uzi_vert.html" ) def test_no_results(self): @@ -656,7 +638,7 @@ def test_no_results(self): "agfdgja,tytul,agfdgafg.html" ) mock = MockFetchUrl() - self.assertEqual(tekstowo.parse_search_results(mock(url)), None) + assert tekstowo.parse_search_results(mock(url)) is None class TekstowoIntegrationTest(TekstowoBaseTest, LyricsAssertions): @@ -687,7 +669,7 @@ def test_no_matching_results(self): # https://github.com/beetbox/beets/issues/4406 # expected return value None lyrics = tekstowo.fetch("Kelly Bailey", "Black Mesa Inbound") - self.assertEqual(lyrics, None) + assert lyrics is None # test LRCLib backend @@ -708,11 +690,11 @@ def test_fetch_synced_lyrics(self, mock_get): mock_get.return_value.status_code = 200 lyrics = lrclib.fetch("la", "la", "la", 999) - self.assertEqual(lyrics, mock_response["plainLyrics"]) + assert lyrics == mock_response["plainLyrics"] self.plugin.config["synced"] = True lyrics = lrclib.fetch("la", "la", "la", 999) - self.assertEqual(lyrics, mock_response["syncedLyrics"]) + assert lyrics == mock_response["syncedLyrics"] @patch("beetsplug.lyrics.requests.get") def test_fetch_plain_lyrics(self, mock_get): @@ -725,7 +707,7 @@ def test_fetch_plain_lyrics(self, mock_get): lyrics = lrclib.fetch("la", "la", "la", 999) - self.assertEqual(lyrics, mock_response["plainLyrics"]) + assert lyrics == mock_response["plainLyrics"] @patch("beetsplug.lyrics.requests.get") def test_fetch_not_found(self, mock_get): @@ -739,7 +721,7 @@ def test_fetch_not_found(self, mock_get): lyrics = lrclib.fetch("la", "la", "la", 999) - self.assertIsNone(lyrics) + assert lyrics is None @patch("beetsplug.lyrics.requests.get") def test_fetch_exception(self, mock_get): @@ -747,7 +729,7 @@ def test_fetch_exception(self, mock_get): lyrics = lrclib.fetch("la", "la", "la", 999) - self.assertIsNone(lyrics) + assert lyrics is None class LRCLibIntegrationTest(LyricsAssertions): @@ -769,12 +751,9 @@ def test_track_with_lyrics(self): ) def test_instrumental_track(self): lyrics = lrclib.fetch( - "Kelly Bailey", - "Black Mesa Inbound", - "Half Life 2 Soundtrack", - 134, + "Kelly Bailey", "Black Mesa Inbound", "Half Life 2 Soundtrack", 134 ) - self.assertIsNone(lyrics) + assert lyrics is None @unittest.skipUnless( os.environ.get("INTEGRATION_TEST", "0") == "1", @@ -782,7 +761,7 @@ def test_instrumental_track(self): ) def test_nonexistent_track(self): lyrics = lrclib.fetch("blah", "blah", "blah", 999) - self.assertIsNone(lyrics) + assert lyrics is None # test utilities @@ -792,27 +771,25 @@ class SlugTests(unittest.TestCase): def test_slug(self): # plain ascii passthrough text = "test" - self.assertEqual(lyrics.slug(text), "test") + assert lyrics.slug(text) == "test" # german unicode and capitals text = "Mørdag" - self.assertEqual(lyrics.slug(text), "mordag") + assert lyrics.slug(text) == "mordag" # more accents and quotes text = "l'été c'est fait pour jouer" - self.assertEqual(lyrics.slug(text), "l-ete-c-est-fait-pour-jouer") + assert lyrics.slug(text) == "l-ete-c-est-fait-pour-jouer" # accents, parens and spaces text = "\xe7afe au lait (boisson)" - self.assertEqual(lyrics.slug(text), "cafe-au-lait-boisson") + assert lyrics.slug(text) == "cafe-au-lait-boisson" text = "Multiple spaces -- and symbols! -- merged" - self.assertEqual( - lyrics.slug(text), "multiple-spaces-and-symbols-merged" - ) + assert lyrics.slug(text) == "multiple-spaces-and-symbols-merged" text = "\u200Bno-width-space" - self.assertEqual(lyrics.slug(text), "no-width-space") + assert lyrics.slug(text) == "no-width-space" # variations of dashes should get standardized dashes = ["\u200D", "\u2010"] for dash1, dash2 in itertools.combinations(dashes, 2): - self.assertEqual(lyrics.slug(dash1), lyrics.slug(dash2)) + assert lyrics.slug(dash1) == lyrics.slug(dash2) diff --git a/test/plugins/test_mbsubmit.py b/test/plugins/test_mbsubmit.py index 01ef522c63..f92d859730 100644 --- a/test/plugins/test_mbsubmit.py +++ b/test/plugins/test_mbsubmit.py @@ -51,7 +51,7 @@ def test_print_tracks_output(self): "01. Tag Track 1 - Tag Artist (0:01)\n" "02. Tag Track 2 - Tag Artist (0:01)" ) - self.assertIn(tracklist, output.getvalue()) + assert tracklist in output.getvalue() def test_print_tracks_output_as_tracks(self): """Test the output of the "print tracks" choice, as singletons.""" @@ -66,4 +66,4 @@ def test_print_tracks_output_as_tracks(self): tracklist = ( "Open files with Picard? " "02. Tag Track 2 - Tag Artist (0:01)" ) - self.assertIn(tracklist, output.getvalue()) + assert tracklist in output.getvalue() diff --git a/test/plugins/test_mbsync.py b/test/plugins/test_mbsync.py index 759a4a2b49..6cfa6704e1 100644 --- a/test/plugins/test_mbsync.py +++ b/test/plugins/test_mbsync.py @@ -57,18 +57,18 @@ def test_update_library(self, track_for_id, album_for_id): with capture_log() as logs: self.run_command("mbsync") - self.assertIn("Sending event: albuminfo_received", logs) - self.assertIn("Sending event: trackinfo_received", logs) + assert "Sending event: albuminfo_received" in logs + assert "Sending event: trackinfo_received" in logs item.load() - self.assertEqual(item.title, "singleton info") + assert item.title == "singleton info" album_item.load() - self.assertEqual(album_item.title, "track info") - self.assertEqual(album_item.mb_trackid, "track id") + assert album_item.title == "track info" + assert album_item.mb_trackid == "track id" album.load() - self.assertEqual(album.album, "album info") + assert album.album == "album info" def test_message_when_skipping(self): config["format_item"] = "$artist - $album - $title" @@ -89,13 +89,13 @@ def test_message_when_skipping(self): "mbsync: Skipping album with no mb_albumid: " + "album info - album info" ) - self.assertEqual(e, logs[0]) + assert e == logs[0] # custom format with capture_log("beets.mbsync") as logs: self.run_command("mbsync", "-f", "'$album'") e = "mbsync: Skipping album with no mb_albumid: 'album info'" - self.assertEqual(e, logs[0]) + assert e == logs[0] # restore the config config["format_item"] = "$artist - $album - $title" @@ -119,13 +119,13 @@ def test_message_when_skipping(self): "mbsync: Skipping singleton with no mb_trackid: " + "album info - album info - old title" ) - self.assertEqual(e, logs[0]) + assert e == logs[0] # custom format with capture_log("beets.mbsync") as logs: self.run_command("mbsync", "-f", "'$title'") e = "mbsync: Skipping singleton with no mb_trackid: 'old title'" - self.assertEqual(e, logs[0]) + assert e == logs[0] def test_message_when_invalid(self): config["format_item"] = "$artist - $album - $title" @@ -149,13 +149,13 @@ def test_message_when_invalid(self): "mbsync: Skipping album with invalid mb_albumid: " + "album info - album info" ) - self.assertEqual(e, logs[0]) + assert e == logs[0] # custom format with capture_log("beets.mbsync") as logs: self.run_command("mbsync", "-f", "'$album'") e = "mbsync: Skipping album with invalid mb_albumid: 'album info'" - self.assertEqual(e, logs[0]) + assert e == logs[0] # restore the config config["format_item"] = "$artist - $album - $title" @@ -180,10 +180,10 @@ def test_message_when_invalid(self): "mbsync: Skipping singleton with invalid mb_trackid: " + "album info - album info - old title" ) - self.assertEqual(e, logs[0]) + assert e == logs[0] # custom format with capture_log("beets.mbsync") as logs: self.run_command("mbsync", "-f", "'$title'") e = "mbsync: Skipping singleton with invalid mb_trackid: 'old title'" - self.assertEqual(e, logs[0]) + assert e == logs[0] diff --git a/test/plugins/test_mpdstats.py b/test/plugins/test_mpdstats.py index 325fd5cd32..dcaf196efa 100644 --- a/test/plugins/test_mpdstats.py +++ b/test/plugins/test_mpdstats.py @@ -31,8 +31,8 @@ def test_update_rating(self): log = Mock() mpdstats = MPDStats(self.lib, log) - self.assertFalse(mpdstats.update_rating(item, True)) - self.assertFalse(mpdstats.update_rating(None, True)) + assert not mpdstats.update_rating(item, True) + assert not mpdstats.update_rating(None, True) def test_get_item(self): item_path = util.normpath("/foo/bar.flac") @@ -42,9 +42,9 @@ def test_get_item(self): log = Mock() mpdstats = MPDStats(self.lib, log) - self.assertEqual(str(mpdstats.get_item(item_path)), str(item)) - self.assertIsNone(mpdstats.get_item("/some/non-existing/path")) - self.assertIn("item not found:", log.info.call_args[0][0]) + assert str(mpdstats.get_item(item_path)) == str(item) + assert mpdstats.get_item("/some/non-existing/path") is None + assert "item not found:" in log.info.call_args[0][0] FAKE_UNKNOWN_STATE = "some-unknown-one" STATUSES = [ diff --git a/test/plugins/test_parentwork.py b/test/plugins/test_parentwork.py index 3ee0e1fb8c..71b9f1fede 100644 --- a/test/plugins/test_parentwork.py +++ b/test/plugins/test_parentwork.py @@ -105,9 +105,7 @@ def test_normal_case_real(self): self.run_command("parentwork") item.load() - self.assertEqual( - item["mb_parentworkid"], "32c8943f-1b27-3a23-8660-4567f4847c94" - ) + assert item["mb_parentworkid"] == "32c8943f-1b27-3a23-8660-4567f4847c94" @unittest.skipUnless( os.environ.get("INTEGRATION_TEST", "0") == "1", @@ -128,9 +126,7 @@ def test_force_real(self): self.run_command("parentwork") item.load() - self.assertEqual( - item["mb_parentworkid"], "32c8943f-1b27-3a23-8660-4567f4847c94" - ) + assert item["mb_parentworkid"] == "32c8943f-1b27-3a23-8660-4567f4847c94" @unittest.skipUnless( os.environ.get("INTEGRATION_TEST", "0") == "1", @@ -152,7 +148,7 @@ def test_no_force_real(self): self.run_command("parentwork") item.load() - self.assertEqual(item["mb_parentworkid"], "XXX") + assert item["mb_parentworkid"] == "XXX" # test different cases, still with Matthew Passion Ouverture or Mozart # requiem @@ -163,13 +159,13 @@ def test_no_force_real(self): ) def test_direct_parent_work_real(self): mb_workid = "2e4a3668-458d-3b2a-8be2-0b08e0d8243a" - self.assertEqual( - "f04b42df-7251-4d86-a5ee-67cfa49580d1", - parentwork.direct_parent_id(mb_workid)[0], + assert ( + "f04b42df-7251-4d86-a5ee-67cfa49580d1" + == parentwork.direct_parent_id(mb_workid)[0] ) - self.assertEqual( - "45afb3b2-18ac-4187-bc72-beb1b1c194ba", - parentwork.work_parent_id(mb_workid)[0], + assert ( + "45afb3b2-18ac-4187-bc72-beb1b1c194ba" + == parentwork.work_parent_id(mb_workid)[0] ) @@ -195,7 +191,7 @@ def test_normal_case(self): self.run_command("parentwork") item.load() - self.assertEqual(item["mb_parentworkid"], "3") + assert item["mb_parentworkid"] == "3" def test_force(self): self.config["parentwork"]["force"] = True @@ -211,7 +207,7 @@ def test_force(self): self.run_command("parentwork") item.load() - self.assertEqual(item["mb_parentworkid"], "3") + assert item["mb_parentworkid"] == "3" def test_no_force(self): self.config["parentwork"]["force"] = False @@ -227,8 +223,8 @@ def test_no_force(self): self.run_command("parentwork") item.load() - self.assertEqual(item["mb_parentworkid"], "XXX") + assert item["mb_parentworkid"] == "XXX" def test_direct_parent_work(self): - self.assertEqual("2", parentwork.direct_parent_id("1")[0]) - self.assertEqual("3", parentwork.work_parent_id("1")[0]) + assert "2" == parentwork.direct_parent_id("1")[0] + assert "3" == parentwork.work_parent_id("1")[0] diff --git a/test/plugins/test_permissions.py b/test/plugins/test_permissions.py index 928dad5689..327304d821 100644 --- a/test/plugins/test_permissions.py +++ b/test/plugins/test_permissions.py @@ -74,13 +74,13 @@ def assertPerms(self, path, typ, expect_success): # noqa x[2], oct(x[1]), ) - self.assertEqual(x[0], check_permissions(path, x[1]), msg=msg) + assert x[0] == check_permissions(path, x[1]), msg def test_convert_perm_from_string(self): - self.assertEqual(convert_perm("10"), 8) + assert convert_perm("10") == 8 def test_convert_perm_from_int(self): - self.assertEqual(convert_perm(10), 8) + assert convert_perm(10) == 8 def test_permissions_on_set_art(self): self.do_set_art(True) @@ -97,6 +97,4 @@ def do_set_art(self, expect_success): artpath = os.path.join(self.temp_dir, b"cover.jpg") touch(artpath) album.set_art(artpath) - self.assertEqual( - expect_success, check_permissions(album.artpath, 0o777) - ) + assert expect_success == check_permissions(album.artpath, 0o777) diff --git a/test/plugins/test_play.py b/test/plugins/test_play.py index 45e87a3286..63f20aeefc 100644 --- a/test/plugins/test_play.py +++ b/test/plugins/test_play.py @@ -20,6 +20,8 @@ import unittest from unittest.mock import ANY, patch +import pytest + from beets.test.helper import CleanupModulesMixin, PluginTestCase, control_stdin from beets.ui import UserError from beets.util import open_anything @@ -50,7 +52,7 @@ def run_and_assert( expected_playlist = expected_playlist or self.item.path.decode("utf-8") exp_playlist = expected_playlist + "\n" with open(open_mock.call_args[0][0][0], "rb") as playlist: - self.assertEqual(exp_playlist, playlist.read().decode("utf-8")) + assert exp_playlist == playlist.read().decode("utf-8") def test_basic(self, open_mock): self.run_and_assert(open_mock) @@ -95,9 +97,8 @@ def test_use_folders(self, open_mock): open_mock.assert_called_once_with(ANY, open_anything()) with open(open_mock.call_args[0][0][0], "rb") as f: playlist = f.read().decode("utf-8") - self.assertEqual( - "{}\n".format(os.path.dirname(self.item.path.decode("utf-8"))), - playlist, + assert ( + f'{os.path.dirname(self.item.path.decode("utf-8"))}\n' == playlist ) def test_raw(self, open_mock): @@ -139,5 +140,5 @@ def test_skip_warning_threshold_bypass(self, open_mock): def test_command_failed(self, open_mock): open_mock.side_effect = OSError("some reason") - with self.assertRaises(UserError): + with pytest.raises(UserError): self.run_command("play", "title:aNiceTitle") diff --git a/test/plugins/test_player.py b/test/plugins/test_player.py index 627b486612..bf466e1b5b 100644 --- a/test/plugins/test_player.py +++ b/test/plugins/test_player.py @@ -12,8 +12,7 @@ # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. -"""Tests for BPD's implementation of the MPD protocol. -""" +"""Tests for BPD's implementation of the MPD protocol.""" import importlib.util import multiprocessing as mp @@ -30,6 +29,7 @@ from unittest import mock import confuse +import pytest import yaml from beets.test.helper import PluginTestCase @@ -77,42 +77,42 @@ class CommandParseTest(unittest.TestCase): def test_no_args(self): s = r"command" c = bpd.Command(s) - self.assertEqual(c.name, "command") - self.assertEqual(c.args, []) + assert c.name == "command" + assert c.args == [] def test_one_unquoted_arg(self): s = r"command hello" c = bpd.Command(s) - self.assertEqual(c.name, "command") - self.assertEqual(c.args, ["hello"]) + assert c.name == "command" + assert c.args == ["hello"] def test_two_unquoted_args(self): s = r"command hello there" c = bpd.Command(s) - self.assertEqual(c.name, "command") - self.assertEqual(c.args, ["hello", "there"]) + assert c.name == "command" + assert c.args == ["hello", "there"] def test_one_quoted_arg(self): s = r'command "hello there"' c = bpd.Command(s) - self.assertEqual(c.name, "command") - self.assertEqual(c.args, ["hello there"]) + assert c.name == "command" + assert c.args == ["hello there"] def test_heterogenous_args(self): s = r'command "hello there" sir' c = bpd.Command(s) - self.assertEqual(c.name, "command") - self.assertEqual(c.args, ["hello there", "sir"]) + assert c.name == "command" + assert c.args == ["hello there", "sir"] def test_quote_in_arg(self): s = r'command "hello \" there"' c = bpd.Command(s) - self.assertEqual(c.args, ['hello " there']) + assert c.args == ['hello " there'] def test_backslash_in_arg(self): s = r'command "hello \\ there"' c = bpd.Command(s) - self.assertEqual(c.args, ["hello \\ there"]) + assert c.args == ["hello \\ there"] class MPCResponse: @@ -248,7 +248,7 @@ def _test(self): response = client.send_command("commands") self._assert_ok(response) implemented = response.data["command"] - self.assertEqual(commands.intersection(implemented), commands) + assert commands.intersection(implemented) == commands return unittest.expectedFailure(_test) if expectedFailure else _test @@ -377,10 +377,8 @@ def run_bpd( def _assert_ok(self, *responses): for response in responses: - self.assertTrue(response is not None) - self.assertTrue( - response.ok, "Response failed: {}".format(response.err_data) - ) + assert response is not None + assert response.ok, f"Response failed: {response.err_data}" def _assert_failed(self, response, code, pos=None): """Check that a command failed with a specific error code. If this @@ -390,11 +388,11 @@ def _assert_failed(self, response, code, pos=None): previous_commands = response[0:pos] self._assert_ok(*previous_commands) response = response[pos] - self.assertFalse(response.ok) + assert not response.ok if pos is not None: - self.assertEqual(pos, response.err_data[1]) + assert pos == response.err_data[1] if code is not None: - self.assertEqual(code, response.err_data[0]) + assert code == response.err_data[0] def _bpd_add(self, client, *items, **kwargs): """Add the given item to the BPD playlist or queue.""" @@ -420,7 +418,7 @@ def _bpd_add(self, client, *items, **kwargs): class BPDTest(BPDTestHelper): def test_server_hello(self): with self.run_bpd(do_hello=False) as client: - self.assertEqual(client.readline(), b"OK MPD 0.16.0\n") + assert client.readline() == b"OK MPD 0.16.0\n" def test_unknown_cmd(self): with self.run_bpd() as client: @@ -462,17 +460,16 @@ def test_cmd_currentsong(self): ("play",), ("currentsong",), ("stop",), ("currentsong",) ) self._assert_ok(*responses) - self.assertEqual("1", responses[1].data["Id"]) - self.assertNotIn("Id", responses[3].data) + assert "1" == responses[1].data["Id"] + assert "Id" not in responses[3].data def test_cmd_currentsong_tagtypes(self): with self.run_bpd() as client: self._bpd_add(client, self.item1) responses = client.send_commands(("play",), ("currentsong",)) self._assert_ok(*responses) - self.assertEqual( - BPDConnectionTest.TAGTYPES.union(BPDQueueTest.METADATA), - set(responses[1].data.keys()), + assert BPDConnectionTest.TAGTYPES.union(BPDQueueTest.METADATA) == set( + responses[1].data.keys() ) def test_cmd_status(self): @@ -493,7 +490,7 @@ def test_cmd_status(self): "state", "volume", } - self.assertEqual(fields_not_playing, set(responses[0].data.keys())) + assert fields_not_playing == set(responses[0].data.keys()) fields_playing = fields_not_playing | { "song", "songid", @@ -505,7 +502,7 @@ def test_cmd_status(self): "nextsong", "nextsongid", } - self.assertEqual(fields_playing, set(responses[2].data.keys())) + assert fields_playing == set(responses[2].data.keys()) def test_cmd_stats(self): with self.run_bpd() as client: @@ -520,7 +517,7 @@ def test_cmd_stats(self): "db_update", "playtime", } - self.assertEqual(details, set(response.data.keys())) + assert details == set(response.data.keys()) def test_cmd_idle(self): def _toggle(c): @@ -547,7 +544,7 @@ def test_cmd_idle_with_pending(self): response1 = client.send_command("random", "1") response2 = client2.send_command("idle") self._assert_ok(response1, response2) - self.assertEqual("options", response2.data["changed"]) + assert "options" == response2.data["changed"] def test_cmd_noidle(self): with self.run_bpd() as client: @@ -590,11 +587,11 @@ def test_cmd_consume(self): ("status",), ) self._assert_ok(*responses) - self.assertEqual(responses[1].data["Id"], responses[3].data["Id"]) - self.assertEqual(["1", "2"], responses[5].data["Id"]) - self.assertEqual("2", responses[8].data["Id"]) - self.assertEqual("1", responses[9].data["consume"]) - self.assertEqual("play", responses[9].data["state"]) + assert responses[1].data["Id"] == responses[3].data["Id"] + assert ["1", "2"] == responses[5].data["Id"] + assert "2" == responses[8].data["Id"] + assert "1" == responses[9].data["consume"] + assert "play" == responses[9].data["state"] def test_cmd_consume_in_reverse(self): with self.run_bpd() as client: @@ -608,9 +605,9 @@ def test_cmd_consume_in_reverse(self): ("status",), ) self._assert_ok(*responses) - self.assertEqual(["1", "2"], responses[2].data["Id"]) - self.assertEqual("1", responses[4].data["Id"]) - self.assertEqual("play", responses[5].data["state"]) + assert ["1", "2"] == responses[2].data["Id"] + assert "1" == responses[4].data["Id"] + assert "play" == responses[5].data["state"] def test_cmd_single(self): with self.run_bpd() as client: @@ -624,10 +621,10 @@ def test_cmd_single(self): ("status",), ) self._assert_ok(*responses) - self.assertEqual("0", responses[0].data["single"]) - self.assertEqual("1", responses[3].data["single"]) - self.assertEqual("play", responses[3].data["state"]) - self.assertEqual("stop", responses[5].data["state"]) + assert "0" == responses[0].data["single"] + assert "1" == responses[3].data["single"] + assert "play" == responses[3].data["state"] + assert "stop" == responses[5].data["state"] def test_cmd_repeat(self): with self.run_bpd() as client: @@ -642,9 +639,9 @@ def test_cmd_repeat(self): ("currentsong",), ) self._assert_ok(*responses) - self.assertEqual("1", responses[2].data["Id"]) - self.assertEqual("2", responses[4].data["Id"]) - self.assertEqual("1", responses[6].data["Id"]) + assert "1" == responses[2].data["Id"] + assert "2" == responses[4].data["Id"] + assert "1" == responses[6].data["Id"] def test_cmd_repeat_with_single(self): with self.run_bpd() as client: @@ -659,9 +656,9 @@ def test_cmd_repeat_with_single(self): ("currentsong",), ) self._assert_ok(*responses) - self.assertEqual("1", responses[3].data["Id"]) - self.assertEqual("play", responses[5].data["state"]) - self.assertEqual("1", responses[6].data["Id"]) + assert "1" == responses[3].data["Id"] + assert "play" == responses[5].data["state"] + assert "1" == responses[6].data["Id"] def test_cmd_repeat_in_reverse(self): with self.run_bpd() as client: @@ -674,8 +671,8 @@ def test_cmd_repeat_in_reverse(self): ("currentsong",), ) self._assert_ok(*responses) - self.assertEqual("1", responses[2].data["Id"]) - self.assertEqual("2", responses[4].data["Id"]) + assert "1" == responses[2].data["Id"] + assert "2" == responses[4].data["Id"] def test_cmd_repeat_with_single_in_reverse(self): with self.run_bpd() as client: @@ -690,9 +687,9 @@ def test_cmd_repeat_with_single_in_reverse(self): ("currentsong",), ) self._assert_ok(*responses) - self.assertEqual("1", responses[3].data["Id"]) - self.assertEqual("play", responses[5].data["state"]) - self.assertEqual("1", responses[6].data["Id"]) + assert "1" == responses[3].data["Id"] + assert "play" == responses[5].data["state"] + assert "1" == responses[6].data["Id"] def test_cmd_crossfade(self): with self.run_bpd() as client: @@ -705,14 +702,14 @@ def test_cmd_crossfade(self): response = client.send_command("crossfade", "0.5") self._assert_failed(responses, bpd.ERROR_ARG, pos=3) self._assert_failed(response, bpd.ERROR_ARG) - self.assertNotIn("xfade", responses[0].data) - self.assertAlmostEqual(123, int(responses[2].data["xfade"])) + assert "xfade" not in responses[0].data + assert 123 == pytest.approx(int(responses[2].data["xfade"])) def test_cmd_mixrampdb(self): with self.run_bpd() as client: responses = client.send_commands(("mixrampdb", "-17"), ("status",)) self._assert_ok(*responses) - self.assertAlmostEqual(-17, float(responses[1].data["mixrampdb"])) + assert -17 == pytest.approx(float(responses[1].data["mixrampdb"])) def test_cmd_mixrampdelay(self): with self.run_bpd() as client: @@ -724,8 +721,8 @@ def test_cmd_mixrampdelay(self): ("mixrampdelay", "-2"), ) self._assert_failed(responses, bpd.ERROR_ARG, pos=4) - self.assertAlmostEqual(2, float(responses[1].data["mixrampdelay"])) - self.assertNotIn("mixrampdelay", responses[3].data) + assert 2 == pytest.approx(float(responses[1].data["mixrampdelay"])) + assert "mixrampdelay" not in responses[3].data def test_cmd_setvol(self): with self.run_bpd() as client: @@ -737,8 +734,8 @@ def test_cmd_setvol(self): ("setvol", "101"), ) self._assert_failed(responses, bpd.ERROR_ARG, pos=4) - self.assertEqual("67", responses[1].data["volume"]) - self.assertEqual("32", responses[3].data["volume"]) + assert "67" == responses[1].data["volume"] + assert "32" == responses[3].data["volume"] def test_cmd_volume(self): with self.run_bpd() as client: @@ -746,7 +743,7 @@ def test_cmd_volume(self): ("setvol", "10"), ("volume", "5"), ("volume", "-2"), ("status",) ) self._assert_ok(*responses) - self.assertEqual("13", responses[3].data["volume"]) + assert "13" == responses[3].data["volume"] def test_cmd_replay_gain(self): with self.run_bpd() as client: @@ -756,7 +753,7 @@ def test_cmd_replay_gain(self): ("replay_gain_mode", "notanoption"), ) self._assert_failed(responses, bpd.ERROR_ARG, pos=2) - self.assertAlmostEqual("track", responses[1].data["replay_gain_mode"]) + assert "track" == responses[1].data["replay_gain_mode"] class BPDControlTest(BPDTestHelper): @@ -780,9 +777,9 @@ def test_cmd_play(self): ("currentsong",), ) self._assert_ok(*responses) - self.assertEqual("stop", responses[0].data["state"]) - self.assertEqual("play", responses[2].data["state"]) - self.assertEqual("2", responses[4].data["Id"]) + assert "stop" == responses[0].data["state"] + assert "play" == responses[2].data["state"] + assert "2" == responses[4].data["Id"] def test_cmd_playid(self): with self.run_bpd() as client: @@ -795,8 +792,8 @@ def test_cmd_playid(self): client.send_commands(("playid", "2"), ("currentsong",)) ) self._assert_ok(*responses) - self.assertEqual("2", responses[1].data["Id"]) - self.assertEqual("2", responses[4].data["Id"]) + assert "2" == responses[1].data["Id"] + assert "2" == responses[4].data["Id"] def test_cmd_pause(self): with self.run_bpd() as client: @@ -805,8 +802,8 @@ def test_cmd_pause(self): ("play",), ("pause",), ("status",), ("currentsong",) ) self._assert_ok(*responses) - self.assertEqual("pause", responses[2].data["state"]) - self.assertEqual("1", responses[3].data["Id"]) + assert "pause" == responses[2].data["state"] + assert "1" == responses[3].data["Id"] def test_cmd_stop(self): with self.run_bpd() as client: @@ -815,8 +812,8 @@ def test_cmd_stop(self): ("play",), ("stop",), ("status",), ("currentsong",) ) self._assert_ok(*responses) - self.assertEqual("stop", responses[2].data["state"]) - self.assertNotIn("Id", responses[3].data) + assert "stop" == responses[2].data["state"] + assert "Id" not in responses[3].data def test_cmd_next(self): with self.run_bpd() as client: @@ -830,9 +827,9 @@ def test_cmd_next(self): ("status",), ) self._assert_ok(*responses) - self.assertEqual("1", responses[1].data["Id"]) - self.assertEqual("2", responses[3].data["Id"]) - self.assertEqual("stop", responses[5].data["state"]) + assert "1" == responses[1].data["Id"] + assert "2" == responses[3].data["Id"] + assert "stop" == responses[5].data["state"] def test_cmd_previous(self): with self.run_bpd() as client: @@ -847,10 +844,10 @@ def test_cmd_previous(self): ("currentsong",), ) self._assert_ok(*responses) - self.assertEqual("2", responses[1].data["Id"]) - self.assertEqual("1", responses[3].data["Id"]) - self.assertEqual("play", responses[5].data["state"]) - self.assertEqual("1", responses[6].data["Id"]) + assert "2" == responses[1].data["Id"] + assert "1" == responses[3].data["Id"] + assert "play" == responses[5].data["state"] + assert "1" == responses[6].data["Id"] class BPDQueueTest(BPDTestHelper): @@ -895,17 +892,16 @@ def test_cmd_playlistinfo(self): ("playlistinfo", "200"), ) self._assert_failed(responses, bpd.ERROR_ARG, pos=3) - self.assertEqual("1", responses[1].data["Id"]) - self.assertEqual(["1", "2"], responses[2].data["Id"]) + assert "1" == responses[1].data["Id"] + assert ["1", "2"] == responses[2].data["Id"] def test_cmd_playlistinfo_tagtypes(self): with self.run_bpd() as client: self._bpd_add(client, self.item1) response = client.send_command("playlistinfo", "0") self._assert_ok(response) - self.assertEqual( - BPDConnectionTest.TAGTYPES.union(BPDQueueTest.METADATA), - set(response.data.keys()), + assert BPDConnectionTest.TAGTYPES.union(BPDQueueTest.METADATA) == set( + response.data.keys() ) def test_cmd_playlistid(self): @@ -915,8 +911,8 @@ def test_cmd_playlistid(self): ("playlistid", "2"), ("playlistid",) ) self._assert_ok(*responses) - self.assertEqual("Track Two Title", responses[0].data["Title"]) - self.assertEqual(["1", "2"], responses[1].data["Track"]) + assert "Track Two Title" == responses[0].data["Title"] + assert ["1", "2"] == responses[1].data["Track"] class BPDPlaylistsTest(BPDTestHelper): @@ -1001,7 +997,7 @@ def test_cmd_search(self): with self.run_bpd() as client: response = client.send_command("search", "track", "1") self._assert_ok(response) - self.assertEqual(self.item1.title, response.data["Title"]) + assert self.item1.title == response.data["Title"] def test_cmd_list(self): with self.run_bpd() as client: @@ -1011,8 +1007,8 @@ def test_cmd_list(self): ("list", "album", "artist", "Artist Name", "track"), ) self._assert_failed(responses, bpd.ERROR_ARG, pos=2) - self.assertEqual("Album Title", responses[0].data["Album"]) - self.assertEqual(["1", "2"], responses[1].data["Track"]) + assert "Album Title" == responses[0].data["Album"] + assert ["1", "2"] == responses[1].data["Track"] def test_cmd_list_three_arg_form(self): with self.run_bpd() as client: @@ -1022,7 +1018,7 @@ def test_cmd_list_three_arg_form(self): ("list", "track", "Artist Name"), ) self._assert_failed(responses, bpd.ERROR_ARG, pos=2) - self.assertEqual(responses[0].data, responses[1].data) + assert responses[0].data == responses[1].data def test_cmd_lsinfo(self): with self.run_bpd() as client: @@ -1036,14 +1032,14 @@ def test_cmd_lsinfo(self): "lsinfo", response2.data["directory"] ) self._assert_ok(response3) - self.assertIn(self.item1.title, response3.data["Title"]) + assert self.item1.title in response3.data["Title"] def test_cmd_count(self): with self.run_bpd() as client: response = client.send_command("count", "track", "1") self._assert_ok(response) - self.assertEqual("1", response.data["songs"]) - self.assertEqual("0", response.data["playtime"]) + assert "1" == response.data["songs"] + assert "0" == response.data["playtime"] class BPDMountsTest(BPDTestHelper): @@ -1130,7 +1126,7 @@ def test_cmd_tagtypes(self): with self.run_bpd() as client: response = client.send_command("tagtypes") self._assert_ok(response) - self.assertEqual(self.TAGTYPES, set(response.data["tagtype"])) + assert self.TAGTYPES == set(response.data["tagtype"]) @unittest.skip def test_tagtypes_mask(self): @@ -1177,9 +1173,9 @@ def test_cmd_decoders(self): with self.run_bpd() as client: response = client.send_command("decoders") self._assert_ok(response) - self.assertEqual("default", response.data["plugin"]) - self.assertEqual("mp3", response.data["suffix"]) - self.assertEqual("audio/mpeg", response.data["mime_type"]) + assert "default" == response.data["plugin"] + assert "mp3" == response.data["suffix"] + assert "audio/mpeg" == response.data["mime_type"] class BPDPeersTest(BPDTestHelper): diff --git a/test/plugins/test_playlist.py b/test/plugins/test_playlist.py index 53f4d8a4e4..ee4059b701 100644 --- a/test/plugins/test_playlist.py +++ b/test/plugins/test_playlist.py @@ -90,13 +90,7 @@ class PlaylistQueryTest: def test_name_query_with_absolute_paths_in_playlist(self): q = "playlist:absolute" results = self.lib.items(q) - self.assertEqual( - {i.title for i in results}, - { - "some item", - "another item", - }, - ) + assert {i.title for i in results} == {"some item", "another item"} def test_path_query_with_absolute_paths_in_playlist(self): q = "playlist:{}".format( @@ -108,24 +102,12 @@ def test_path_query_with_absolute_paths_in_playlist(self): ) ) results = self.lib.items(q) - self.assertEqual( - {i.title for i in results}, - { - "some item", - "another item", - }, - ) + assert {i.title for i in results} == {"some item", "another item"} def test_name_query_with_relative_paths_in_playlist(self): q = "playlist:relative" results = self.lib.items(q) - self.assertEqual( - {i.title for i in results}, - { - "some item", - "another item", - }, - ) + assert {i.title for i in results} == {"some item", "another item"} def test_path_query_with_relative_paths_in_playlist(self): q = "playlist:{}".format( @@ -137,18 +119,12 @@ def test_path_query_with_relative_paths_in_playlist(self): ) ) results = self.lib.items(q) - self.assertEqual( - {i.title for i in results}, - { - "some item", - "another item", - }, - ) + assert {i.title for i in results} == {"some item", "another item"} def test_name_query_with_nonexisting_playlist(self): q = "playlist:nonexisting" results = self.lib.items(q) - self.assertEqual(set(results), set()) + assert set(results) == set() def test_path_query_with_nonexisting_playlist(self): q = "playlist:{}".format( @@ -161,7 +137,7 @@ def test_path_query_with_nonexisting_playlist(self): ) ) results = self.lib.items(q) - self.assertEqual(set(results), set()) + assert set(results) == set() class PlaylistTestRelativeToLib(PlaylistQueryTest, PlaylistTestCase): @@ -313,28 +289,22 @@ def test_item_moved(self): with open(playlist_path) as f: lines = [line.strip() for line in f.readlines()] - self.assertEqual( - lines, - [ - os.path.join(self.music_dir, "a", "b", "c.mp3"), - os.path.join(self.music_dir, "g", "h", "i.mp3"), - os.path.join(self.music_dir, "nonexisting.mp3"), - ], - ) + assert lines == [ + os.path.join(self.music_dir, "a", "b", "c.mp3"), + os.path.join(self.music_dir, "g", "h", "i.mp3"), + os.path.join(self.music_dir, "nonexisting.mp3"), + ] # Check playlist with relative paths playlist_path = os.path.join(self.playlist_dir, "relative.m3u") with open(playlist_path) as f: lines = [line.strip() for line in f.readlines()] - self.assertEqual( - lines, - [ - os.path.join("a", "b", "c.mp3"), - os.path.join("g", "h", "i.mp3"), - "nonexisting.mp3", - ], - ) + assert lines == [ + os.path.join("a", "b", "c.mp3"), + os.path.join("g", "h", "i.mp3"), + "nonexisting.mp3", + ] class PlaylistTestItemRemoved(PlaylistUpdateTest, PlaylistTestCase): @@ -365,23 +335,14 @@ def test_item_removed(self): with open(playlist_path) as f: lines = [line.strip() for line in f.readlines()] - self.assertEqual( - lines, - [ - os.path.join(self.music_dir, "a", "b", "c.mp3"), - os.path.join(self.music_dir, "nonexisting.mp3"), - ], - ) + assert lines == [ + os.path.join(self.music_dir, "a", "b", "c.mp3"), + os.path.join(self.music_dir, "nonexisting.mp3"), + ] # Check playlist with relative paths playlist_path = os.path.join(self.playlist_dir, "relative.m3u") with open(playlist_path) as f: lines = [line.strip() for line in f.readlines()] - self.assertEqual( - lines, - [ - os.path.join("a", "b", "c.mp3"), - "nonexisting.mp3", - ], - ) + assert lines == [os.path.join("a", "b", "c.mp3"), "nonexisting.mp3"] diff --git a/test/plugins/test_plexupdate.py b/test/plugins/test_plexupdate.py index e84e798cf1..f319db6cee 100644 --- a/test/plugins/test_plexupdate.py +++ b/test/plugins/test_plexupdate.py @@ -83,7 +83,7 @@ def test_get_music_section(self): self.add_response_get_music_section() # Test if section key is "2" out of the mocking data. - self.assertEqual( + assert ( get_music_section( self.config["plex"]["host"], self.config["plex"]["port"], @@ -91,8 +91,8 @@ def test_get_music_section(self): self.config["plex"]["library_name"].get(), self.config["plex"]["secure"], self.config["plex"]["ignore_cert_errors"], - ), - "2", + ) + == "2" ) @responses.activate @@ -100,7 +100,7 @@ def test_get_named_music_section(self): # Adding response. self.add_response_get_music_section("My Music Library") - self.assertEqual( + assert ( get_music_section( self.config["plex"]["host"], self.config["plex"]["port"], @@ -108,8 +108,8 @@ def test_get_named_music_section(self): "My Music Library", self.config["plex"]["secure"], self.config["plex"]["ignore_cert_errors"], - ), - "2", + ) + == "2" ) @responses.activate @@ -119,7 +119,7 @@ def test_update_plex(self): self.add_response_update_plex() # Testing status code of the mocking request. - self.assertEqual( + assert ( update_plex( self.config["plex"]["host"], self.config["plex"]["port"], @@ -127,6 +127,6 @@ def test_update_plex(self): self.config["plex"]["library_name"].get(), self.config["plex"]["secure"], self.config["plex"]["ignore_cert_errors"], - ).status_code, - 200, + ).status_code + == 200 ) diff --git a/test/plugins/test_plugin_mediafield.py b/test/plugins/test_plugin_mediafield.py index 6f933c54cb..39b5aa3d22 100644 --- a/test/plugins/test_plugin_mediafield.py +++ b/test/plugins/test_plugin_mediafield.py @@ -19,6 +19,7 @@ import shutil import mediafile +import pytest from beets.library import Item from beets.plugins import BeetsPlugin @@ -59,7 +60,7 @@ def test_extended_field_write(self): mf.save() mf = mediafile.MediaFile(mf.path) - self.assertEqual(mf.customtag, "F#") + assert mf.customtag == "F#" finally: delattr(mediafile.MediaFile, "customtag") @@ -75,7 +76,7 @@ def test_extended_list_field_write(self): mf.save() mf = mediafile.MediaFile(mf.path) - self.assertEqual(mf.customlisttag, ["a", "b"]) + assert mf.customlisttag == ["a", "b"] finally: delattr(mediafile.MediaFile, "customlisttag") @@ -87,12 +88,12 @@ def test_write_extended_tag_from_item(self): try: mf = self._mediafile_fixture("empty") - self.assertIsNone(mf.customtag) + assert mf.customtag is None item = Item(path=mf.path, customtag="Gb") item.write() mf = mediafile.MediaFile(mf.path) - self.assertEqual(mf.customtag, "Gb") + assert mf.customtag == "Gb" finally: delattr(mediafile.MediaFile, "customtag") @@ -108,18 +109,20 @@ def test_read_flexible_attribute_from_file(self): mf.save() item = Item.from_path(mf.path) - self.assertEqual(item["customtag"], "F#") + assert item["customtag"] == "F#" finally: delattr(mediafile.MediaFile, "customtag") Item._media_fields.remove("customtag") def test_invalid_descriptor(self): - with self.assertRaises(ValueError) as cm: + with pytest.raises( + ValueError, match="must be an instance of MediaField" + ): mediafile.MediaFile.add_field("somekey", True) - self.assertIn("must be an instance of MediaField", str(cm.exception)) def test_overwrite_property(self): - with self.assertRaises(ValueError) as cm: + with pytest.raises( + ValueError, match='property "artist" already exists' + ): mediafile.MediaFile.add_field("artist", mediafile.MediaField()) - self.assertIn('property "artist" already exists', str(cm.exception)) diff --git a/test/plugins/test_random.py b/test/plugins/test_random.py index 84edb4bc6a..626f31779e 100644 --- a/test/plugins/test_random.py +++ b/test/plugins/test_random.py @@ -20,6 +20,8 @@ import unittest from random import Random +import pytest + from beets import random from beets.test.helper import TestHelper @@ -74,6 +76,6 @@ def experiment(field, histogram=False): mean1, stdev1, median1 = experiment("artist") mean2, stdev2, median2 = experiment("track") - self.assertAlmostEqual(0, median1, delta=1) - self.assertAlmostEqual(len(self.items) // 2, median2, delta=1) - self.assertGreater(stdev2, stdev1) + assert 0 == pytest.approx(median1, abs=1) + assert len(self.items) // 2 == pytest.approx(median2, abs=1) + assert stdev2 > stdev1 diff --git a/test/plugins/test_replaygain.py b/test/plugins/test_replaygain.py index 348725a6f2..091298766f 100644 --- a/test/plugins/test_replaygain.py +++ b/test/plugins/test_replaygain.py @@ -16,6 +16,7 @@ import unittest from typing import ClassVar +import pytest from mediafile import MediaFile from beets import config @@ -129,11 +130,11 @@ def test_cli_saves_track_gain(self): self._add_album(2) for item in self.lib.items(): - self.assertIsNone(item.rg_track_peak) - self.assertIsNone(item.rg_track_gain) + assert item.rg_track_peak is None + assert item.rg_track_gain is None mediafile = MediaFile(item.path) - self.assertIsNone(mediafile.rg_track_peak) - self.assertIsNone(mediafile.rg_track_gain) + assert mediafile.rg_track_peak is None + assert mediafile.rg_track_gain is None self.run_command("replaygain") @@ -146,14 +147,14 @@ def test_cli_saves_track_gain(self): self.skipTest("decoder plugins could not be loaded.") for item in self.lib.items(): - self.assertIsNotNone(item.rg_track_peak) - self.assertIsNotNone(item.rg_track_gain) + assert item.rg_track_peak is not None + assert item.rg_track_gain is not None mediafile = MediaFile(item.path) - self.assertAlmostEqual( - mediafile.rg_track_peak, item.rg_track_peak, places=6 + assert mediafile.rg_track_peak == pytest.approx( + item.rg_track_peak, abs=1e-6 ) - self.assertAlmostEqual( - mediafile.rg_track_gain, item.rg_track_gain, places=2 + assert mediafile.rg_track_gain == pytest.approx( + item.rg_track_gain, abs=1e-2 ) def test_cli_skips_calculated_tracks(self): @@ -167,9 +168,9 @@ def test_cli_skips_calculated_tracks(self): self.run_command("replaygain") item_rg.load() - self.assertIsNotNone(item_rg.rg_track_gain) - self.assertIsNotNone(item_rg.rg_track_peak) - self.assertIsNone(item_rg.r128_track_gain) + assert item_rg.rg_track_gain is not None + assert item_rg.rg_track_peak is not None + assert item_rg.r128_track_gain is None item_rg.rg_track_gain += 1.0 item_rg.rg_track_peak += 1.0 @@ -179,9 +180,9 @@ def test_cli_skips_calculated_tracks(self): if self.has_r128_support: item_r128.load() - self.assertIsNotNone(item_r128.r128_track_gain) - self.assertIsNone(item_r128.rg_track_gain) - self.assertIsNone(item_r128.rg_track_peak) + assert item_r128.r128_track_gain is not None + assert item_r128.rg_track_gain is None + assert item_r128.rg_track_peak is None item_r128.r128_track_gain += 1.0 item_r128.store() @@ -190,12 +191,12 @@ def test_cli_skips_calculated_tracks(self): self.run_command("replaygain") item_rg.load() - self.assertEqual(item_rg.rg_track_gain, rg_track_gain) - self.assertEqual(item_rg.rg_track_peak, rg_track_peak) + assert item_rg.rg_track_gain == rg_track_gain + assert item_rg.rg_track_peak == rg_track_peak if self.has_r128_support: item_r128.load() - self.assertEqual(item_r128.r128_track_gain, r128_track_gain) + assert item_r128.r128_track_gain == r128_track_gain def test_cli_does_not_skip_wrong_tag_type(self): """Check that items that have tags of the wrong type won't be skipped.""" @@ -225,23 +226,23 @@ def test_cli_does_not_skip_wrong_tag_type(self): item_rg.load() item_r128.load() - self.assertIsNotNone(item_rg.rg_track_gain) - self.assertIsNotNone(item_rg.rg_track_peak) + assert item_rg.rg_track_gain is not None + assert item_rg.rg_track_peak is not None # FIXME: Should the plugin null this field? - # self.assertIsNone(item_rg.r128_track_gain) + # assert item_rg.r128_track_gain is None - self.assertIsNotNone(item_r128.r128_track_gain) + assert item_r128.r128_track_gain is not None # FIXME: Should the plugin null these fields? - # self.assertIsNone(item_r128.rg_track_gain) - # self.assertIsNone(item_r128.rg_track_peak) + # assert item_r128.rg_track_gain is None + # assert item_r128.rg_track_peak is None def test_cli_saves_album_gain_to_file(self): self._add_album(2) for item in self.lib.items(): mediafile = MediaFile(item.path) - self.assertIsNone(mediafile.rg_album_peak) - self.assertIsNone(mediafile.rg_album_gain) + assert mediafile.rg_album_peak is None + assert mediafile.rg_album_gain is None self.run_command("replaygain", "-a") @@ -253,11 +254,11 @@ def test_cli_saves_album_gain_to_file(self): gains.append(mediafile.rg_album_gain) # Make sure they are all the same - self.assertEqual(max(peaks), min(peaks)) - self.assertEqual(max(gains), min(gains)) + assert max(peaks) == min(peaks) + assert max(gains) == min(gains) - self.assertNotEqual(max(gains), 0.0) - self.assertNotEqual(max(peaks), 0.0) + assert max(gains) != 0.0 + assert max(peaks) != 0.0 def test_cli_writes_only_r128_tags(self): if not self.has_r128_support: @@ -274,11 +275,11 @@ def test_cli_writes_only_r128_tags(self): for item in album.items(): mediafile = MediaFile(item.path) # does not write REPLAYGAIN_* tags - self.assertIsNone(mediafile.rg_track_gain) - self.assertIsNone(mediafile.rg_album_gain) + assert mediafile.rg_track_gain is None + assert mediafile.rg_album_gain is None # writes R128_* tags - self.assertIsNotNone(mediafile.r128_track_gain) - self.assertIsNotNone(mediafile.r128_album_gain) + assert mediafile.r128_track_gain is not None + assert mediafile.r128_album_gain is not None def test_targetlevel_has_effect(self): album = self._add_album(1) @@ -293,7 +294,7 @@ def analyse(target_level): gain_relative_to_84 = analyse(84) gain_relative_to_89 = analyse(89) - self.assertNotEqual(gain_relative_to_84, gain_relative_to_89) + assert gain_relative_to_84 != gain_relative_to_89 def test_r128_targetlevel_has_effect(self): if not self.has_r128_support: @@ -315,7 +316,7 @@ def analyse(target_level): gain_relative_to_84 = analyse(84) gain_relative_to_89 = analyse(89) - self.assertNotEqual(gain_relative_to_84, gain_relative_to_89) + assert gain_relative_to_84 != gain_relative_to_89 def test_per_disc(self): # Use the per_disc option and add a little more concurrency. @@ -326,8 +327,8 @@ def test_per_disc(self): # FIXME: Add fixtures with known track/album gain (within a suitable # tolerance) so that we can actually check per-disc operation here. for item in album.items(): - self.assertIsNotNone(item.rg_track_gain) - self.assertIsNotNone(item.rg_album_gain) + assert item.rg_track_gain is not None + assert item.rg_album_gain is not None @unittest.skipIf(not GST_AVAILABLE, "gstreamer cannot be found") @@ -365,8 +366,8 @@ def test_import_converted(self): # FIXME: Add fixtures with known track/album gain (within a # suitable tolerance) so that we can actually check correct # operation here. - self.assertIsNotNone(item.rg_track_gain) - self.assertIsNotNone(item.rg_album_gain) + assert item.rg_track_gain is not None + assert item.rg_album_gain is not None @unittest.skipIf(not GST_AVAILABLE, "gstreamer cannot be found") diff --git a/test/plugins/test_smartplaylist.py b/test/plugins/test_smartplaylist.py index 4959c5c8fd..a50f3e6227 100644 --- a/test/plugins/test_smartplaylist.py +++ b/test/plugins/test_smartplaylist.py @@ -18,6 +18,8 @@ from tempfile import mkdtemp from unittest.mock import MagicMock, Mock, PropertyMock +import pytest + from beets import config from beets.dbcore import OrQuery from beets.dbcore.query import FixedFieldSort, MultipleSort, NullSort @@ -31,13 +33,13 @@ class SmartPlaylistTest(BeetsTestCase): def test_build_queries(self): spl = SmartPlaylistPlugin() - self.assertIsNone(spl._matched_playlists) - self.assertIsNone(spl._unmatched_playlists) + assert spl._matched_playlists is None + assert spl._unmatched_playlists is None config["smartplaylist"]["playlists"].set([]) spl.build_queries() - self.assertEqual(spl._matched_playlists, set()) - self.assertEqual(spl._unmatched_playlists, set()) + assert spl._matched_playlists == set() + assert spl._unmatched_playlists == set() config["smartplaylist"]["playlists"].set( [ @@ -47,7 +49,7 @@ def test_build_queries(self): ] ) spl.build_queries() - self.assertEqual(spl._matched_playlists, set()) + assert spl._matched_playlists == set() foo_foo = parse_query_string("FOO foo", Item) baz_baz = parse_query_string("BAZ baz", Item) baz_baz2 = parse_query_string("BAZ baz", Album) @@ -57,14 +59,11 @@ def test_build_queries(self): parse_query_string("BAR bar2", Album)[0], ) ) - self.assertEqual( - spl._unmatched_playlists, - { - ("foo", foo_foo, (None, None)), - ("baz", baz_baz, baz_baz2), - ("bar", (None, None), (bar_bar, None)), - }, - ) + assert spl._unmatched_playlists == { + ("foo", foo_foo, (None, None)), + ("baz", baz_baz, baz_baz2), + ("bar", (None, None), (bar_bar, None)), + } def test_build_queries_with_sorts(self): spl = SmartPlaylistPlugin() @@ -88,19 +87,16 @@ def test_build_queries_with_sorts(self): spl.build_queries() sorts = {name: sort for name, (_, sort), _ in spl._unmatched_playlists} - asseq = self.assertEqual # less cluttered code sort = FixedFieldSort # short cut since we're only dealing with this - asseq(sorts["no_sort"], NullSort()) - asseq(sorts["one_sort"], sort("year")) - asseq(sorts["only_empty_sorts"], None) - asseq(sorts["one_non_empty_sort"], sort("year")) - asseq( - sorts["multiple_sorts"], - MultipleSort([sort("year"), sort("genre", False)]), + assert sorts["no_sort"] == NullSort() + assert sorts["one_sort"] == sort("year") + assert sorts["only_empty_sorts"] is None + assert sorts["one_non_empty_sort"] == sort("year") + assert sorts["multiple_sorts"] == MultipleSort( + [sort("year"), sort("genre", False)] ) - asseq( - sorts["mixed"], - MultipleSort([sort("year"), sort("genre"), sort("id", False)]), + assert sorts["mixed"] == MultipleSort( + [sort("year"), sort("genre"), sort("id", False)] ) def test_matches(self): @@ -109,21 +105,21 @@ def test_matches(self): a = MagicMock(Album) i = MagicMock(Item) - self.assertFalse(spl.matches(i, None, None)) - self.assertFalse(spl.matches(a, None, None)) + assert not spl.matches(i, None, None) + assert not spl.matches(a, None, None) query = Mock() query.match.side_effect = {i: True}.__getitem__ - self.assertTrue(spl.matches(i, query, None)) - self.assertFalse(spl.matches(a, query, None)) + assert spl.matches(i, query, None) + assert not spl.matches(a, query, None) a_query = Mock() a_query.match.side_effect = {a: True}.__getitem__ - self.assertFalse(spl.matches(i, None, a_query)) - self.assertTrue(spl.matches(a, None, a_query)) + assert not spl.matches(i, None, a_query) + assert spl.matches(a, None, a_query) - self.assertTrue(spl.matches(i, query, a_query)) - self.assertTrue(spl.matches(a, query, a_query)) + assert spl.matches(i, query, a_query) + assert spl.matches(a, query, a_query) def test_db_changes(self): spl = SmartPlaylistPlugin() @@ -138,18 +134,18 @@ def test_db_changes(self): spl.matches = Mock(return_value=False) spl.db_change(None, "nothing") - self.assertEqual(spl._unmatched_playlists, {pl1, pl2, pl3}) - self.assertEqual(spl._matched_playlists, set()) + assert spl._unmatched_playlists == {pl1, pl2, pl3} + assert spl._matched_playlists == set() spl.matches.side_effect = lambda _, q, __: q == "q3" spl.db_change(None, "matches 3") - self.assertEqual(spl._unmatched_playlists, {pl1, pl2}) - self.assertEqual(spl._matched_playlists, {pl3}) + assert spl._unmatched_playlists == {pl1, pl2} + assert spl._matched_playlists == {pl3} spl.matches.side_effect = lambda _, q, __: q == "q1" spl.db_change(None, "matches 3") - self.assertEqual(spl._matched_playlists, {pl1, pl3}) - self.assertEqual(spl._unmatched_playlists, {pl2}) + assert spl._matched_playlists == {pl1, pl3} + assert spl._unmatched_playlists == {pl2} def test_playlist_update(self): spl = SmartPlaylistPlugin() @@ -187,7 +183,7 @@ def test_playlist_update(self): content = f.read() rmtree(syspath(dir)) - self.assertEqual(content, b"/tagada.mp3\n") + assert content == b"/tagada.mp3\n" def test_playlist_update_output_extm3u(self): spl = SmartPlaylistPlugin() @@ -232,11 +228,11 @@ def test_playlist_update_output_extm3u(self): content = f.read() rmtree(syspath(dir)) - self.assertEqual( - content, - b"#EXTM3U\n" + assert ( + content + == b"#EXTM3U\n" + b"#EXTINF:300,fake artist - fake title\n" - + b"http://beets:8337/files/tagada.mp3\n", + + b"http://beets:8337/files/tagada.mp3\n" ) def test_playlist_update_output_extm3u_fields(self): @@ -284,11 +280,11 @@ def test_playlist_update_output_extm3u_fields(self): content = f.read() rmtree(syspath(dir)) - self.assertEqual( - content, - b"#EXTM3U\n" + assert ( + content + == b"#EXTM3U\n" + b'#EXTINF:300 id="456" genre="Fake Genre",Fake Artist - fake Title\n' - + b"/tagada.mp3\n", + + b"/tagada.mp3\n" ) def test_playlist_update_uri_format(self): @@ -334,7 +330,7 @@ def test_playlist_update_uri_format(self): content = f.read() rmtree(syspath(dir)) - self.assertEqual(content, b"http://beets:8337/item/3/file\n") + assert content == b"http://beets:8337/item/3/file\n" class SmartPlaylistCLITest(PluginTestCase): @@ -353,22 +349,22 @@ def setUp(self): config["smartplaylist"]["playlist_dir"].set(fsdecode(self.temp_dir)) def test_splupdate(self): - with self.assertRaises(UserError): + with pytest.raises(UserError): self.run_with_output("splupdate", "tagada") self.run_with_output("splupdate", "my_playlist") m3u_path = path.join(self.temp_dir, b"my_playlist.m3u") self.assertExists(m3u_path) with open(syspath(m3u_path), "rb") as f: - self.assertEqual(f.read(), self.item.path + b"\n") + assert f.read() == self.item.path + b"\n" remove(syspath(m3u_path)) self.run_with_output("splupdate", "my_playlist.m3u") with open(syspath(m3u_path), "rb") as f: - self.assertEqual(f.read(), self.item.path + b"\n") + assert f.read() == self.item.path + b"\n" remove(syspath(m3u_path)) self.run_with_output("splupdate") for name in (b"my_playlist.m3u", b"all.m3u"): with open(path.join(self.temp_dir, name), "rb") as f: - self.assertEqual(f.read(), self.item.path + b"\n") + assert f.read() == self.item.path + b"\n" diff --git a/test/plugins/test_spotify.py b/test/plugins/test_spotify.py index d61c3e85a2..a2336df10d 100644 --- a/test/plugins/test_spotify.py +++ b/test/plugins/test_spotify.py @@ -45,12 +45,12 @@ def setUp(self): def test_args(self): opts = ArgumentsMock("fail", True) - self.assertFalse(self.spotify._parse_opts(opts)) + assert not self.spotify._parse_opts(opts) opts = ArgumentsMock("list", False) - self.assertTrue(self.spotify._parse_opts(opts)) + assert self.spotify._parse_opts(opts) def test_empty_query(self): - self.assertIsNone(self.spotify._match_library_tracks(self.lib, "1=2")) + assert self.spotify._match_library_tracks(self.lib, "1=2") is None @responses.activate def test_missing_request(self): @@ -75,14 +75,14 @@ def test_missing_request(self): length=10, ) item.add(self.lib) - self.assertEqual([], self.spotify._match_library_tracks(self.lib, "")) + assert [] == self.spotify._match_library_tracks(self.lib, "") params = _params(responses.calls[0].request.url) query = params["q"][0] - self.assertIn("duifhjslkef", query) - self.assertIn("artist:ujydfsuihse", query) - self.assertIn("album:lkajsdflakjsd", query) - self.assertEqual(params["type"], ["track"]) + assert "duifhjslkef" in query + assert "artist:ujydfsuihse" in query + assert "album:lkajsdflakjsd" in query + assert params["type"] == ["track"] @responses.activate def test_track_request(self): @@ -108,16 +108,16 @@ def test_track_request(self): ) item.add(self.lib) results = self.spotify._match_library_tracks(self.lib, "Happy") - self.assertEqual(1, len(results)) - self.assertEqual("6NPVjNh8Jhru9xOmyQigds", results[0]["id"]) + assert 1 == len(results) + assert "6NPVjNh8Jhru9xOmyQigds" == results[0]["id"] self.spotify._output_match_results(results) params = _params(responses.calls[0].request.url) query = params["q"][0] - self.assertIn("Happy", query) - self.assertIn("artist:Pharrell Williams", query) - self.assertIn("album:Despicable Me 2", query) - self.assertEqual(params["type"], ["track"]) + assert "Happy" in query + assert "artist:Pharrell Williams" in query + assert "album:Despicable Me 2" in query + assert params["type"] == ["track"] @responses.activate def test_track_for_id(self): @@ -174,5 +174,5 @@ def test_track_for_id(self): item.add(self.lib) results = self.spotify._match_library_tracks(self.lib, "Happy") - self.assertEqual(1, len(results)) - self.assertEqual("6NPVjNh8Jhru9xOmyQigds", results[0]["id"]) + assert 1 == len(results) + assert "6NPVjNh8Jhru9xOmyQigds" == results[0]["id"] diff --git a/test/plugins/test_the.py b/test/plugins/test_the.py index 3a48092df0..bf073301b8 100644 --- a/test/plugins/test_the.py +++ b/test/plugins/test_the.py @@ -7,55 +7,43 @@ class ThePluginTest(BeetsTestCase): def test_unthe_with_default_patterns(self): - self.assertEqual(ThePlugin().unthe("", PATTERN_THE), "") - self.assertEqual( - ThePlugin().unthe("The Something", PATTERN_THE), "Something, The" - ) - self.assertEqual(ThePlugin().unthe("The The", PATTERN_THE), "The, The") - self.assertEqual( - ThePlugin().unthe("The The", PATTERN_THE), "The, The" - ) - self.assertEqual( - ThePlugin().unthe("The The X", PATTERN_THE), "The X, The" - ) - self.assertEqual(ThePlugin().unthe("the The", PATTERN_THE), "The, the") - self.assertEqual( - ThePlugin().unthe("Protected The", PATTERN_THE), "Protected The" - ) - self.assertEqual(ThePlugin().unthe("A Boy", PATTERN_A), "Boy, A") - self.assertEqual(ThePlugin().unthe("a girl", PATTERN_A), "girl, a") - self.assertEqual(ThePlugin().unthe("An Apple", PATTERN_A), "Apple, An") - self.assertEqual( - ThePlugin().unthe("An A Thing", PATTERN_A), "A Thing, An" - ) - self.assertEqual( - ThePlugin().unthe("the An Arse", PATTERN_A), "the An Arse" - ) - self.assertEqual( - ThePlugin().unthe("TET - Travailleur", PATTERN_THE), - "TET - Travailleur", + assert ThePlugin().unthe("", PATTERN_THE) == "" + assert ( + ThePlugin().unthe("The Something", PATTERN_THE) == "Something, The" + ) + assert ThePlugin().unthe("The The", PATTERN_THE) == "The, The" + assert ThePlugin().unthe("The The", PATTERN_THE) == "The, The" + assert ThePlugin().unthe("The The X", PATTERN_THE) == "The X, The" + assert ThePlugin().unthe("the The", PATTERN_THE) == "The, the" + assert ( + ThePlugin().unthe("Protected The", PATTERN_THE) == "Protected The" + ) + assert ThePlugin().unthe("A Boy", PATTERN_A) == "Boy, A" + assert ThePlugin().unthe("a girl", PATTERN_A) == "girl, a" + assert ThePlugin().unthe("An Apple", PATTERN_A) == "Apple, An" + assert ThePlugin().unthe("An A Thing", PATTERN_A) == "A Thing, An" + assert ThePlugin().unthe("the An Arse", PATTERN_A) == "the An Arse" + assert ( + ThePlugin().unthe("TET - Travailleur", PATTERN_THE) + == "TET - Travailleur" ) def test_unthe_with_strip(self): config["the"]["strip"] = True - self.assertEqual( - ThePlugin().unthe("The Something", PATTERN_THE), "Something" - ) - self.assertEqual(ThePlugin().unthe("An A", PATTERN_A), "A") + assert ThePlugin().unthe("The Something", PATTERN_THE) == "Something" + assert ThePlugin().unthe("An A", PATTERN_A) == "A" def test_template_function_with_defaults(self): ThePlugin().patterns = [PATTERN_THE, PATTERN_A] - self.assertEqual(ThePlugin().the_template_func("The The"), "The, The") - self.assertEqual(ThePlugin().the_template_func("An A"), "A, An") + assert ThePlugin().the_template_func("The The") == "The, The" + assert ThePlugin().the_template_func("An A") == "A, An" def test_custom_pattern(self): config["the"]["patterns"] = ["^test\\s"] config["the"]["format"] = FORMAT - self.assertEqual( - ThePlugin().the_template_func("test passed"), "passed, test" - ) + assert ThePlugin().the_template_func("test passed") == "passed, test" def test_custom_format(self): config["the"]["patterns"] = [PATTERN_THE, PATTERN_A] config["the"]["format"] = "{1} ({0})" - self.assertEqual(ThePlugin().the_template_func("The A"), "The (A)") + assert ThePlugin().the_template_func("The A") == "The (A)" diff --git a/test/plugins/test_thumbnails.py b/test/plugins/test_thumbnails.py index 14e0de8cf5..07775995c1 100644 --- a/test/plugins/test_thumbnails.py +++ b/test/plugins/test_thumbnails.py @@ -18,6 +18,8 @@ from tempfile import mkdtemp from unittest.mock import Mock, call, patch +import pytest + from beets.test.helper import BeetsTestCase from beets.util import bytestring_path, syspath from beetsplug.thumbnails import ( @@ -58,7 +60,7 @@ def test_check_local_ok(self, mock_giouri, mock_artresizer, mock_os): mock_artresizer.shared.local = False mock_artresizer.shared.can_write_metadata = False plugin = ThumbnailsPlugin() - self.assertFalse(plugin._check_local_ok()) + assert not plugin._check_local_ok() # test dirs creation mock_artresizer.shared.local = True @@ -74,29 +76,27 @@ def exists(path): mock_os.path.exists = exists plugin = ThumbnailsPlugin() mock_os.makedirs.assert_called_once_with(syspath(NORMAL_DIR)) - self.assertTrue(plugin._check_local_ok()) + assert plugin._check_local_ok() # test metadata writer function mock_os.path.exists = lambda _: True mock_artresizer.shared.local = True mock_artresizer.shared.can_write_metadata = False - with self.assertRaises(RuntimeError): + with pytest.raises(RuntimeError): ThumbnailsPlugin() mock_artresizer.shared.local = True mock_artresizer.shared.can_write_metadata = True - self.assertTrue(ThumbnailsPlugin()._check_local_ok()) + assert ThumbnailsPlugin()._check_local_ok() # test URI getter function giouri_inst = mock_giouri.return_value giouri_inst.available = True - self.assertEqual(ThumbnailsPlugin().get_uri, giouri_inst.uri) + assert ThumbnailsPlugin().get_uri == giouri_inst.uri giouri_inst.available = False - self.assertEqual( - ThumbnailsPlugin().get_uri.__self__.__class__, PathlibURI - ) + assert ThumbnailsPlugin().get_uri.__self__.__class__ == PathlibURI @patch("beetsplug.thumbnails.ThumbnailsPlugin._check_local_ok") @patch("beetsplug.thumbnails.ArtResizer") @@ -159,7 +159,7 @@ def os_stat(target): mock_os.stat.side_effect = os_stat plugin.make_cover_thumbnail(album, 12345, thumbnail_dir) - self.assertEqual(mock_resize.call_count, 0) + assert mock_resize.call_count == 0 # and with force plugin.config["force"] = True @@ -173,17 +173,19 @@ def test_make_dolphin_cover_thumbnail(self, _): album = Mock(path=tmp, artpath=os.path.join(tmp, b"cover.jpg")) plugin.make_dolphin_cover_thumbnail(album) with open(os.path.join(tmp, b".directory"), "rb") as f: - self.assertEqual( - f.read().splitlines(), [b"[Desktop Entry]", b"Icon=./cover.jpg"] - ) + assert f.read().splitlines() == [ + b"[Desktop Entry]", + b"Icon=./cover.jpg", + ] # not rewritten when it already exists (yup that's a big limitation) album.artpath = b"/my/awesome/art.tiff" plugin.make_dolphin_cover_thumbnail(album) with open(os.path.join(tmp, b".directory"), "rb") as f: - self.assertEqual( - f.read().splitlines(), [b"[Desktop Entry]", b"Icon=./cover.jpg"] - ) + assert f.read().splitlines() == [ + b"[Desktop Entry]", + b"Icon=./cover.jpg", + ] rmtree(syspath(tmp)) @@ -199,20 +201,20 @@ def test_process_album(self, mock_artresizer, _): # no art album = Mock(artpath=None) plugin.process_album(album) - self.assertEqual(get_size.call_count, 0) - self.assertEqual(make_dolphin.call_count, 0) + assert get_size.call_count == 0 + assert make_dolphin.call_count == 0 # cannot get art size album.artpath = b"/path/to/art" get_size.return_value = None plugin.process_album(album) get_size.assert_called_once_with(b"/path/to/art") - self.assertEqual(make_cover.call_count, 0) + assert make_cover.call_count == 0 # dolphin tests plugin.config["dolphin"] = False plugin.process_album(album) - self.assertEqual(make_dolphin.call_count, 0) + assert make_dolphin.call_count == 0 plugin.config["dolphin"] = True plugin.process_album(album) @@ -253,9 +255,9 @@ def test_invokations(self, mock_decargs, _): def test_thumbnail_file_name(self, mock_basedir): plug = ThumbnailsPlugin() plug.get_uri = Mock(return_value="file:///my/uri") - self.assertEqual( - plug.thumbnail_file_name(b"idontcare"), - b"9488f5797fbe12ffb316d607dfd93d04.png", + assert ( + plug.thumbnail_file_name(b"idontcare") + == b"9488f5797fbe12ffb316d607dfd93d04.png" ) def test_uri(self): @@ -263,12 +265,12 @@ def test_uri(self): if not gio.available: self.skipTest("GIO library not found") - self.assertEqual(gio.uri("/foo"), "file:///") # silent fail - self.assertEqual(gio.uri(b"/foo"), "file:///foo") - self.assertEqual(gio.uri(b"/foo!"), "file:///foo!") - self.assertEqual( - gio.uri(b"/music/\xec\x8b\xb8\xec\x9d\xb4"), - "file:///music/%EC%8B%B8%EC%9D%B4", + assert gio.uri("/foo") == "file:///" # silent fail + assert gio.uri(b"/foo") == "file:///foo" + assert gio.uri(b"/foo!") == "file:///foo!" + assert ( + gio.uri(b"/music/\xec\x8b\xb8\xec\x9d\xb4") + == "file:///music/%EC%8B%B8%EC%9D%B4" ) diff --git a/test/plugins/test_types_plugin.py b/test/plugins/test_types_plugin.py index 4ee3b4b34e..b41e9bb184 100644 --- a/test/plugins/test_types_plugin.py +++ b/test/plugins/test_types_plugin.py @@ -16,6 +16,7 @@ import time from datetime import datetime +import pytest from confuse import ConfigValueError from beets.test.helper import PluginTestCase @@ -30,15 +31,15 @@ def test_integer_modify_and_query(self): # Do not match unset values out = self.list("myint:1..3") - self.assertEqual("", out) + assert "" == out self.modify("myint=2") item.load() - self.assertEqual(item["myint"], 2) + assert item["myint"] == 2 # Match in range out = self.list("myint:1..3") - self.assertIn("aaa", out) + assert "aaa" in out def test_album_integer_modify_and_query(self): self.config["types"] = {"myint": "int"} @@ -46,15 +47,15 @@ def test_album_integer_modify_and_query(self): # Do not match unset values out = self.list_album("myint:1..3") - self.assertEqual("", out) + assert "" == out self.modify("-a", "myint=2") album.load() - self.assertEqual(album["myint"], 2) + assert album["myint"] == 2 # Match in range out = self.list_album("myint:1..3") - self.assertIn("aaa", out) + assert "aaa" in out def test_float_modify_and_query(self): self.config["types"] = {"myfloat": "float"} @@ -62,15 +63,15 @@ def test_float_modify_and_query(self): # Do not match unset values out = self.list("myfloat:10..0") - self.assertEqual("", out) + assert "" == out self.modify("myfloat=-9.1") item.load() - self.assertEqual(item["myfloat"], -9.1) + assert item["myfloat"] == -9.1 # Match in range out = self.list("myfloat:-10..0") - self.assertIn("aaa", out) + assert "aaa" in out def test_bool_modify_and_query(self): self.config["types"] = {"mybool": "bool"} @@ -80,28 +81,28 @@ def test_bool_modify_and_query(self): # Do not match unset values out = self.list("mybool:true, mybool:false") - self.assertEqual("", out) + assert "" == out # Set true self.modify("mybool=1", "artist:true") true.load() - self.assertTrue(true["mybool"]) + assert true["mybool"] # Set false self.modify("mybool=false", "artist:false") false.load() - self.assertFalse(false["mybool"]) + assert not false["mybool"] # Query bools out = self.list("mybool:true", "$artist $mybool") - self.assertEqual("true True", out) + assert "true True" == out out = self.list("mybool:false", "$artist $mybool") # Dealing with unset fields? - # self.assertEqual('false False', out) + # assert 'false False' == out # out = self.list('mybool:', '$artist $mybool') - # self.assertIn('unset $mybool', out) + # assert 'unset $mybool' in out def test_date_modify_and_query(self): self.config["types"] = {"mydate": "date"} @@ -112,27 +113,27 @@ def test_date_modify_and_query(self): # Do not match unset values out = self.list("mydate:..2000") - self.assertEqual("", out) + assert "" == out self.modify("mydate=1999-01-01", "artist:prince") old.load() - self.assertEqual(old["mydate"], mktime(1999, 1, 1)) + assert old["mydate"] == mktime(1999, 1, 1) self.modify("mydate=1999-12-30", "artist:britney") new.load() - self.assertEqual(new["mydate"], mktime(1999, 12, 30)) + assert new["mydate"] == mktime(1999, 12, 30) # Match in range out = self.list("mydate:..1999-07", "$artist $mydate") - self.assertEqual("prince 1999-01-01", out) + assert "prince 1999-01-01" == out # FIXME some sort of timezone issue here # out = self.list('mydate:1999-12-30', '$artist $mydate') - # self.assertEqual('britney 1999-12-30', out) + # assert 'britney 1999-12-30' == out def test_unknown_type_error(self): self.config["types"] = {"flex": "unkown type"} - with self.assertRaises(ConfigValueError): + with pytest.raises(ConfigValueError): self.run_command("ls") def test_template_if_def(self): @@ -154,29 +155,20 @@ def test_template_if_def(self): without_fields = self.add_item(artist="britney") int_template = "%ifdef{playcount,Play count: $playcount,Not played}" - self.assertEqual( - with_fields.evaluate_template(int_template), "Play count: 10" - ) - self.assertEqual( - without_fields.evaluate_template(int_template), "Not played" - ) + assert with_fields.evaluate_template(int_template) == "Play count: 10" + assert without_fields.evaluate_template(int_template) == "Not played" float_template = "%ifdef{rating,Rating: $rating,Not rated}" - self.assertEqual( - with_fields.evaluate_template(float_template), "Rating: 5.0" - ) - self.assertEqual( - without_fields.evaluate_template(float_template), "Not rated" - ) + assert with_fields.evaluate_template(float_template) == "Rating: 5.0" + assert without_fields.evaluate_template(float_template) == "Not rated" bool_template = "%ifdef{starred,Starred: $starred,Not starred}" - self.assertIn( - with_fields.evaluate_template(bool_template).lower(), - ("starred: true", "starred: yes", "starred: y"), - ) - self.assertEqual( - without_fields.evaluate_template(bool_template), "Not starred" + assert with_fields.evaluate_template(bool_template).lower() in ( + "starred: true", + "starred: yes", + "starred: y", ) + assert without_fields.evaluate_template(bool_template) == "Not starred" def modify(self, *args): return self.run_with_output( diff --git a/test/plugins/test_web.py b/test/plugins/test_web.py index 6c703af5f6..2ad07bbe5d 100644 --- a/test/plugins/test_web.py +++ b/test/plugins/test_web.py @@ -4,6 +4,7 @@ import os.path import platform import shutil +from collections import Counter from beets import logging from beets.library import Album, Item @@ -74,8 +75,8 @@ def test_config_include_paths_true(self): self.path_prefix + os.sep + os.path.join(b"path_1").decode("utf-8") ) - self.assertEqual(response.status_code, 200) - self.assertEqual(res_json["path"], expected_path) + assert response.status_code == 200 + assert res_json["path"] == expected_path web.app.config["INCLUDE_PATHS"] = False @@ -89,8 +90,8 @@ def test_config_include_artpaths_true(self): + os.path.join(b"somewhere2", b"art_path_2").decode("utf-8") ) - self.assertEqual(response.status_code, 200) - self.assertEqual(res_json["artpath"], expected_path) + assert response.status_code == 200 + assert res_json["artpath"] == expected_path web.app.config["INCLUDE_PATHS"] = False @@ -99,44 +100,44 @@ def test_config_include_paths_false(self): response = self.client.get("/item/1") res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertNotIn("path", res_json) + assert response.status_code == 200 + assert "path" not in res_json def test_config_include_artpaths_false(self): web.app.config["INCLUDE_PATHS"] = False response = self.client.get("/album/2") res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertNotIn("artpath", res_json) + assert response.status_code == 200 + assert "artpath" not in res_json def test_get_all_items(self): response = self.client.get("/item/") res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertEqual(len(res_json["items"]), 3) + assert response.status_code == 200 + assert len(res_json["items"]) == 3 def test_get_single_item_by_id(self): response = self.client.get("/item/1") res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertEqual(res_json["id"], 1) - self.assertEqual(res_json["title"], "title") + assert response.status_code == 200 + assert res_json["id"] == 1 + assert res_json["title"] == "title" def test_get_multiple_items_by_id(self): response = self.client.get("/item/1,2") res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertEqual(len(res_json["items"]), 2) + assert response.status_code == 200 + assert len(res_json["items"]) == 2 response_titles = {item["title"] for item in res_json["items"]} - self.assertEqual(response_titles, {"title", "another title"}) + assert response_titles == {"title", "another title"} def test_get_single_item_not_found(self): response = self.client.get("/item/4") - self.assertEqual(response.status_code, 404) + assert response.status_code == 404 def test_get_single_item_by_path(self): data_path = os.path.join(_common.RSRC, b"full.mp3") @@ -144,8 +145,8 @@ def test_get_single_item_by_path(self): response = self.client.get("/item/path/" + data_path.decode("utf-8")) res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertEqual(res_json["title"], "full") + assert response.status_code == 200 + assert res_json["title"] == "full" def test_get_single_item_by_path_not_found_if_not_in_library(self): data_path = os.path.join(_common.RSRC, b"full.mp3") @@ -153,51 +154,51 @@ def test_get_single_item_by_path_not_found_if_not_in_library(self): # to the library. response = self.client.get("/item/path/" + data_path.decode("utf-8")) - self.assertEqual(response.status_code, 404) + assert response.status_code == 404 def test_get_item_empty_query(self): """testing item query: """ response = self.client.get("/item/query/") res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertEqual(len(res_json["items"]), 3) + assert response.status_code == 200 + assert len(res_json["items"]) == 3 def test_get_simple_item_query(self): """testing item query: another""" response = self.client.get("/item/query/another") res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertEqual(len(res_json["results"]), 1) - self.assertEqual(res_json["results"][0]["title"], "another title") + assert response.status_code == 200 + assert len(res_json["results"]) == 1 + assert res_json["results"][0]["title"] == "another title" def test_query_item_string(self): """testing item query: testattr:ABC""" response = self.client.get("/item/query/testattr%3aABC") res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertEqual(len(res_json["results"]), 1) - self.assertEqual(res_json["results"][0]["title"], "and a third") + assert response.status_code == 200 + assert len(res_json["results"]) == 1 + assert res_json["results"][0]["title"] == "and a third" def test_query_item_regex(self): """testing item query: testattr::[A-C]+""" response = self.client.get("/item/query/testattr%3a%3a[A-C]%2b") res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertEqual(len(res_json["results"]), 1) - self.assertEqual(res_json["results"][0]["title"], "and a third") + assert response.status_code == 200 + assert len(res_json["results"]) == 1 + assert res_json["results"][0]["title"] == "and a third" def test_query_item_regex_backslash(self): # """ testing item query: testattr::\w+ """ response = self.client.get("/item/query/testattr%3a%3a%5cw%2b") res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertEqual(len(res_json["results"]), 1) - self.assertEqual(res_json["results"][0]["title"], "and a third") + assert response.status_code == 200 + assert len(res_json["results"]) == 1 + assert res_json["results"][0]["title"] == "and a third" def test_query_item_path(self): # """ testing item query: path:\somewhere\a """ @@ -210,95 +211,95 @@ def test_query_item_path(self): ) res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertEqual(len(res_json["results"]), 1) - self.assertEqual(res_json["results"][0]["title"], "another title") + assert response.status_code == 200 + assert len(res_json["results"]) == 1 + assert res_json["results"][0]["title"] == "another title" def test_get_all_albums(self): response = self.client.get("/album/") res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) + assert response.status_code == 200 response_albums = [album["album"] for album in res_json["albums"]] - self.assertCountEqual(response_albums, ["album", "other album"]) + assert Counter(response_albums) == {"album": 1, "other album": 1} def test_get_single_album_by_id(self): response = self.client.get("/album/2") res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertEqual(res_json["id"], 2) - self.assertEqual(res_json["album"], "other album") + assert response.status_code == 200 + assert res_json["id"] == 2 + assert res_json["album"] == "other album" def test_get_multiple_albums_by_id(self): response = self.client.get("/album/1,2") res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) + assert response.status_code == 200 response_albums = [album["album"] for album in res_json["albums"]] - self.assertCountEqual(response_albums, ["album", "other album"]) + assert Counter(response_albums) == {"album": 1, "other album": 1} def test_get_album_empty_query(self): response = self.client.get("/album/query/") res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertEqual(len(res_json["albums"]), 2) + assert response.status_code == 200 + assert len(res_json["albums"]) == 2 def test_get_simple_album_query(self): response = self.client.get("/album/query/other") res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertEqual(len(res_json["results"]), 1) - self.assertEqual(res_json["results"][0]["album"], "other album") - self.assertEqual(res_json["results"][0]["id"], 2) + assert response.status_code == 200 + assert len(res_json["results"]) == 1 + assert res_json["results"][0]["album"] == "other album" + assert res_json["results"][0]["id"] == 2 def test_get_album_details(self): response = self.client.get("/album/2?expand") res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertEqual(len(res_json["items"]), 2) - self.assertEqual(res_json["items"][0]["album"], "other album") - self.assertEqual(res_json["items"][1]["album"], "other album") + assert response.status_code == 200 + assert len(res_json["items"]) == 2 + assert res_json["items"][0]["album"] == "other album" + assert res_json["items"][1]["album"] == "other album" response_track_titles = {item["title"] for item in res_json["items"]} - self.assertEqual(response_track_titles, {"title", "and a third"}) + assert response_track_titles == {"title", "and a third"} def test_query_album_string(self): """testing query: albumtest:xy""" response = self.client.get("/album/query/albumtest%3axy") res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertEqual(len(res_json["results"]), 1) - self.assertEqual(res_json["results"][0]["album"], "album") + assert response.status_code == 200 + assert len(res_json["results"]) == 1 + assert res_json["results"][0]["album"] == "album" def test_query_album_artpath_regex(self): """testing query: artpath::art_""" response = self.client.get("/album/query/artpath%3a%3aart_") res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertEqual(len(res_json["results"]), 1) - self.assertEqual(res_json["results"][0]["album"], "other album") + assert response.status_code == 200 + assert len(res_json["results"]) == 1 + assert res_json["results"][0]["album"] == "other album" def test_query_album_regex_backslash(self): # """ testing query: albumtest::\w+ """ response = self.client.get("/album/query/albumtest%3a%3a%5cw%2b") res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertEqual(len(res_json["results"]), 1) - self.assertEqual(res_json["results"][0]["album"], "album") + assert response.status_code == 200 + assert len(res_json["results"]) == 1 + assert res_json["results"][0]["album"] == "album" def test_get_stats(self): response = self.client.get("/stats") res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertEqual(res_json["items"], 3) - self.assertEqual(res_json["albums"], 2) + assert response.status_code == 200 + assert res_json["items"] == 3 + assert res_json["albums"] == 2 def test_delete_item_id(self): web.app.config["READONLY"] = False @@ -311,17 +312,17 @@ def test_delete_item_id(self): # Check we can find the temporary item we just created response = self.client.get("/item/" + str(item_id)) res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertEqual(res_json["id"], item_id) + assert response.status_code == 200 + assert res_json["id"] == item_id # Delete item by id response = self.client.delete("/item/" + str(item_id)) res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) + assert response.status_code == 200 # Check the item has gone response = self.client.get("/item/" + str(item_id)) - self.assertEqual(response.status_code, 404) + assert response.status_code == 404 # Note: if this fails, the item may still be around # and may cause other tests to fail @@ -331,26 +332,26 @@ def test_delete_item_without_file(self): # Create an item with a file ipath = os.path.join(self.temp_dir, b"testfile1.mp3") shutil.copy(os.path.join(_common.RSRC, b"full.mp3"), ipath) - self.assertTrue(os.path.exists(ipath)) + assert os.path.exists(ipath) item_id = self.lib.add(Item.from_path(ipath)) # Check we can find the temporary item we just created response = self.client.get("/item/" + str(item_id)) res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertEqual(res_json["id"], item_id) + assert response.status_code == 200 + assert res_json["id"] == item_id # Delete item by id, without deleting file response = self.client.delete("/item/" + str(item_id)) res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) + assert response.status_code == 200 # Check the item has gone response = self.client.get("/item/" + str(item_id)) - self.assertEqual(response.status_code, 404) + assert response.status_code == 404 # Check the file has not gone - self.assertTrue(os.path.exists(ipath)) + assert os.path.exists(ipath) os.remove(ipath) def test_delete_item_with_file(self): @@ -359,26 +360,26 @@ def test_delete_item_with_file(self): # Create an item with a file ipath = os.path.join(self.temp_dir, b"testfile2.mp3") shutil.copy(os.path.join(_common.RSRC, b"full.mp3"), ipath) - self.assertTrue(os.path.exists(ipath)) + assert os.path.exists(ipath) item_id = self.lib.add(Item.from_path(ipath)) # Check we can find the temporary item we just created response = self.client.get("/item/" + str(item_id)) res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertEqual(res_json["id"], item_id) + assert response.status_code == 200 + assert res_json["id"] == item_id # Delete item by id, with file response = self.client.delete("/item/" + str(item_id) + "?delete") res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) + assert response.status_code == 200 # Check the item has gone response = self.client.get("/item/" + str(item_id)) - self.assertEqual(response.status_code, 404) + assert response.status_code == 404 # Check the file has gone - self.assertFalse(os.path.exists(ipath)) + assert not os.path.exists(ipath) def test_delete_item_query(self): web.app.config["READONLY"] = False @@ -391,19 +392,19 @@ def test_delete_item_query(self): # Check we can find the temporary item we just created response = self.client.get("/item/query/test_delete_item_query") res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertEqual(len(res_json["results"]), 1) + assert response.status_code == 200 + assert len(res_json["results"]) == 1 # Delete item by query response = self.client.delete("/item/query/test_delete_item_query") res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) + assert response.status_code == 200 # Check the item has gone response = self.client.get("/item/query/test_delete_item_query") res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertEqual(len(res_json["results"]), 0) + assert response.status_code == 200 + assert len(res_json["results"]) == 0 def test_delete_item_all_fails(self): """DELETE is not supported for list all""" @@ -412,7 +413,7 @@ def test_delete_item_all_fails(self): # Delete all items response = self.client.delete("/item/") - self.assertEqual(response.status_code, 405) + assert response.status_code == 405 # Note: if this fails, all items have gone and rest of # tests will fail! @@ -428,18 +429,18 @@ def test_delete_item_id_readonly(self): # Check we can find the temporary item we just created response = self.client.get("/item/" + str(item_id)) res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertEqual(res_json["id"], item_id) + assert response.status_code == 200 + assert res_json["id"] == item_id # Try to delete item by id response = self.client.delete("/item/" + str(item_id)) - self.assertEqual(response.status_code, 405) + assert response.status_code == 405 # Check the item has not gone response = self.client.get("/item/" + str(item_id)) res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertEqual(res_json["id"], item_id) + assert response.status_code == 200 + assert res_json["id"] == item_id # Remove it self.lib.get_item(item_id).remove() @@ -455,18 +456,18 @@ def test_delete_item_query_readonly(self): # Check we can find the temporary item we just created response = self.client.get("/item/query/test_delete_item_q_ro") res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertEqual(len(res_json["results"]), 1) + assert response.status_code == 200 + assert len(res_json["results"]) == 1 # Try to delete item by query response = self.client.delete("/item/query/test_delete_item_q_ro") - self.assertEqual(response.status_code, 405) + assert response.status_code == 405 # Check the item has not gone response = self.client.get("/item/query/test_delete_item_q_ro") res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertEqual(len(res_json["results"]), 1) + assert response.status_code == 200 + assert len(res_json["results"]) == 1 # Remove it self.lib.get_item(item_id).remove() @@ -482,17 +483,17 @@ def test_delete_album_id(self): # Check we can find the temporary album we just created response = self.client.get("/album/" + str(album_id)) res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertEqual(res_json["id"], album_id) + assert response.status_code == 200 + assert res_json["id"] == album_id # Delete album by id response = self.client.delete("/album/" + str(album_id)) res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) + assert response.status_code == 200 # Check the album has gone response = self.client.get("/album/" + str(album_id)) - self.assertEqual(response.status_code, 404) + assert response.status_code == 404 # Note: if this fails, the album may still be around # and may cause other tests to fail @@ -507,19 +508,19 @@ def test_delete_album_query(self): # Check we can find the temporary album we just created response = self.client.get("/album/query/test_delete_album_query") res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertEqual(len(res_json["results"]), 1) + assert response.status_code == 200 + assert len(res_json["results"]) == 1 # Delete album response = self.client.delete("/album/query/test_delete_album_query") res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) + assert response.status_code == 200 # Check the album has gone response = self.client.get("/album/query/test_delete_album_query") res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertEqual(len(res_json["results"]), 0) + assert response.status_code == 200 + assert len(res_json["results"]) == 0 def test_delete_album_all_fails(self): """DELETE is not supported for list all""" @@ -528,7 +529,7 @@ def test_delete_album_all_fails(self): # Delete all albums response = self.client.delete("/album/") - self.assertEqual(response.status_code, 405) + assert response.status_code == 405 # Note: if this fails, all albums have gone and rest of # tests will fail! @@ -544,18 +545,18 @@ def test_delete_album_id_readonly(self): # Check we can find the temporary album we just created response = self.client.get("/album/" + str(album_id)) res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertEqual(res_json["id"], album_id) + assert response.status_code == 200 + assert res_json["id"] == album_id # Try to delete album by id response = self.client.delete("/album/" + str(album_id)) - self.assertEqual(response.status_code, 405) + assert response.status_code == 405 # Check the item has not gone response = self.client.get("/album/" + str(album_id)) res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertEqual(res_json["id"], album_id) + assert response.status_code == 200 + assert res_json["id"] == album_id # Remove it self.lib.get_album(album_id).remove() @@ -573,18 +574,18 @@ def test_delete_album_query_readonly(self): # Check we can find the temporary album we just created response = self.client.get("/album/query/test_delete_album_query_ro") res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertEqual(len(res_json["results"]), 1) + assert response.status_code == 200 + assert len(res_json["results"]) == 1 # Try to delete album response = self.client.delete("/album/query/test_delete_album_query_ro") - self.assertEqual(response.status_code, 405) + assert response.status_code == 405 # Check the album has not gone response = self.client.get("/album/query/test_delete_album_query_ro") res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertEqual(len(res_json["results"]), 1) + assert response.status_code == 200 + assert len(res_json["results"]) == 1 # Remove it self.lib.get_album(album_id).remove() @@ -604,11 +605,10 @@ def test_patch_item_id(self): # Check we can find the temporary item we just created response = self.client.get("/item/" + str(item_id)) res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertEqual(res_json["id"], item_id) - self.assertEqual( - [res_json["test_patch_f1"], res_json["test_patch_f2"]], ["1", "Old"] - ) + assert response.status_code == 200 + assert res_json["id"] == item_id + assert res_json["test_patch_f1"] == "1" + assert res_json["test_patch_f2"] == "Old" # Patch item by id # patch_json = json.JSONEncoder().encode({"test_patch_f2": "New"}]}) @@ -616,20 +616,18 @@ def test_patch_item_id(self): "/item/" + str(item_id), json={"test_patch_f2": "New"} ) res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertEqual(res_json["id"], item_id) - self.assertEqual( - [res_json["test_patch_f1"], res_json["test_patch_f2"]], ["1", "New"] - ) + assert response.status_code == 200 + assert res_json["id"] == item_id + assert res_json["test_patch_f1"] == "1" + assert res_json["test_patch_f2"] == "New" # Check the update has really worked response = self.client.get("/item/" + str(item_id)) res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertEqual(res_json["id"], item_id) - self.assertEqual( - [res_json["test_patch_f1"], res_json["test_patch_f2"]], ["1", "New"] - ) + assert response.status_code == 200 + assert res_json["id"] == item_id + assert res_json["test_patch_f1"] == "1" + assert res_json["test_patch_f2"] == "New" # Remove the item self.lib.get_item(item_id).remove() @@ -651,18 +649,17 @@ def test_patch_item_id_readonly(self): # Check we can find the temporary item we just created response = self.client.get("/item/" + str(item_id)) res_json = json.loads(response.data.decode("utf-8")) - self.assertEqual(response.status_code, 200) - self.assertEqual(res_json["id"], item_id) - self.assertEqual( - [res_json["test_patch_f1"], res_json["test_patch_f2"]], ["2", "Old"] - ) + assert response.status_code == 200 + assert res_json["id"] == item_id + assert res_json["test_patch_f1"] == "2" + assert res_json["test_patch_f2"] == "Old" # Patch item by id # patch_json = json.JSONEncoder().encode({"test_patch_f2": "New"}) response = self.client.patch( "/item/" + str(item_id), json={"test_patch_f2": "New"} ) - self.assertEqual(response.status_code, 405) + assert response.status_code == 405 # Remove the item self.lib.get_item(item_id).remove() @@ -670,9 +667,9 @@ def test_patch_item_id_readonly(self): def test_get_item_file(self): ipath = os.path.join(self.temp_dir, b"testfile2.mp3") shutil.copy(os.path.join(_common.RSRC, b"full.mp3"), ipath) - self.assertTrue(os.path.exists(ipath)) + assert os.path.exists(ipath) item_id = self.lib.add(Item.from_path(ipath)) response = self.client.get("/item/" + str(item_id) + "/file") - self.assertEqual(response.status_code, 200) + assert response.status_code == 200 diff --git a/test/plugins/test_zero.py b/test/plugins/test_zero.py index c267c0708b..e21e2cabb2 100644 --- a/test/plugins/test_zero.py +++ b/test/plugins/test_zero.py @@ -25,10 +25,10 @@ def test_no_patterns(self): item.write() mf = MediaFile(syspath(item.path)) - self.assertIsNone(mf.comments) - self.assertIsNone(mf.month) - self.assertEqual(mf.title, "Title") - self.assertEqual(mf.year, 2000) + assert mf.comments is None + assert mf.month is None + assert mf.title == "Title" + assert mf.year == 2000 def test_pattern_match(self): item = self.add_item_fixture(comments="encoded by encoder") @@ -40,7 +40,7 @@ def test_pattern_match(self): item.write() mf = MediaFile(syspath(item.path)) - self.assertIsNone(mf.comments) + assert mf.comments is None def test_pattern_nomatch(self): item = self.add_item_fixture(comments="recorded at place") @@ -52,7 +52,7 @@ def test_pattern_nomatch(self): item.write() mf = MediaFile(syspath(item.path)) - self.assertEqual(mf.comments, "recorded at place") + assert mf.comments == "recorded at place" def test_do_not_change_database(self): item = self.add_item_fixture(year=2000) @@ -61,7 +61,7 @@ def test_do_not_change_database(self): with self.configure_plugin({"fields": ["year"]}): item.write() - self.assertEqual(item["year"], 2000) + assert item["year"] == 2000 def test_change_database(self): item = self.add_item_fixture(year=2000) @@ -72,7 +72,7 @@ def test_change_database(self): ): item.write() - self.assertEqual(item["year"], 0) + assert item["year"] == 0 def test_album_art(self): path = self.create_mediafile_fixture(images=["jpg"]) @@ -82,7 +82,7 @@ def test_album_art(self): item.write() mf = MediaFile(syspath(path)) - self.assertFalse(mf.images) + assert not mf.images def test_auto_false(self): item = self.add_item_fixture(year=2000) @@ -93,7 +93,7 @@ def test_auto_false(self): ): item.write() - self.assertEqual(item["year"], 2000) + assert item["year"] == 2000 def test_subcommand_update_database_true(self): item = self.add_item_fixture( @@ -110,10 +110,10 @@ def test_subcommand_update_database_true(self): mf = MediaFile(syspath(item.path)) item = self.lib.get_item(item_id) - self.assertEqual(item["year"], 2016) - self.assertEqual(mf.year, 2016) - self.assertIsNone(mf.comments) - self.assertEqual(item["comments"], "") + assert item["year"] == 2016 + assert mf.year == 2016 + assert mf.comments is None + assert item["comments"] == "" def test_subcommand_update_database_false(self): item = self.add_item_fixture( @@ -130,10 +130,10 @@ def test_subcommand_update_database_false(self): mf = MediaFile(syspath(item.path)) item = self.lib.get_item(item_id) - self.assertEqual(item["year"], 2016) - self.assertEqual(mf.year, 2016) - self.assertEqual(item["comments"], "test comment") - self.assertIsNone(mf.comments) + assert item["year"] == 2016 + assert mf.year == 2016 + assert item["comments"] == "test comment" + assert mf.comments is None def test_subcommand_query_include(self): item = self.add_item_fixture( @@ -149,8 +149,8 @@ def test_subcommand_query_include(self): mf = MediaFile(syspath(item.path)) - self.assertEqual(mf.year, 2016) - self.assertIsNone(mf.comments) + assert mf.year == 2016 + assert mf.comments is None def test_subcommand_query_exclude(self): item = self.add_item_fixture( @@ -166,14 +166,14 @@ def test_subcommand_query_exclude(self): mf = MediaFile(syspath(item.path)) - self.assertEqual(mf.year, 2016) - self.assertEqual(mf.comments, "test comment") + assert mf.year == 2016 + assert mf.comments == "test comment" def test_no_fields(self): item = self.add_item_fixture(year=2016) item.write() mediafile = MediaFile(syspath(item.path)) - self.assertEqual(mediafile.year, 2016) + assert mediafile.year == 2016 item_id = item.id @@ -182,14 +182,14 @@ def test_no_fields(self): item = self.lib.get_item(item_id) - self.assertEqual(item["year"], 2016) - self.assertEqual(mediafile.year, 2016) + assert item["year"] == 2016 + assert mediafile.year == 2016 def test_whitelist_and_blacklist(self): item = self.add_item_fixture(year=2016) item.write() mf = MediaFile(syspath(item.path)) - self.assertEqual(mf.year, 2016) + assert mf.year == 2016 item_id = item.id @@ -200,8 +200,8 @@ def test_whitelist_and_blacklist(self): item = self.lib.get_item(item_id) - self.assertEqual(item["year"], 2016) - self.assertEqual(mf.year, 2016) + assert item["year"] == 2016 + assert mf.year == 2016 def test_keep_fields(self): item = self.add_item_fixture(year=2016, comments="test comment") @@ -216,8 +216,8 @@ def test_keep_fields(self): z = ZeroPlugin() z.write_event(item, item.path, tags) - self.assertIsNone(tags["comments"]) - self.assertEqual(tags["year"], 2016) + assert tags["comments"] is None + assert tags["year"] == 2016 def test_keep_fields_removes_preserved_tags(self): self.config["zero"]["keep_fields"] = ["year"] @@ -226,7 +226,7 @@ def test_keep_fields_removes_preserved_tags(self): z = ZeroPlugin() - self.assertNotIn("id", z.fields_to_progs) + assert "id" not in z.fields_to_progs def test_fields_removes_preserved_tags(self): self.config["zero"]["fields"] = ["year id"] @@ -234,7 +234,7 @@ def test_fields_removes_preserved_tags(self): z = ZeroPlugin() - self.assertNotIn("id", z.fields_to_progs) + assert "id" not in z.fields_to_progs def test_empty_query_n_response_no_changes(self): item = self.add_item_fixture( @@ -250,7 +250,7 @@ def test_empty_query_n_response_no_changes(self): mf = MediaFile(syspath(item.path)) item = self.lib.get_item(item_id) - self.assertEqual(item["year"], 2016) - self.assertEqual(mf.year, 2016) - self.assertEqual(mf.comments, "test comment") - self.assertEqual(item["comments"], "test comment") + assert item["year"] == 2016 + assert mf.year == 2016 + assert mf.comments == "test comment" + assert item["comments"] == "test comment" diff --git a/test/test_art_resize.py b/test/test_art_resize.py index 3a2d5cc83a..fb628bca76 100644 --- a/test/test_art_resize.py +++ b/test/test_art_resize.py @@ -77,8 +77,9 @@ def _test_img_resize(self, backend): ) self.assertExists(im_a) # target size was achieved - self.assertLess( - os.stat(syspath(im_a)).st_size, os.stat(syspath(im_95_qual)).st_size + assert ( + os.stat(syspath(im_a)).st_size + < os.stat(syspath(im_95_qual)).st_size ) # Attempt with lower initial quality @@ -98,8 +99,9 @@ def _test_img_resize(self, backend): ) self.assertExists(im_b) # Check high (initial) quality still gives a smaller filesize - self.assertLess( - os.stat(syspath(im_b)).st_size, os.stat(syspath(im_75_qual)).st_size + assert ( + os.stat(syspath(im_b)).st_size + < os.stat(syspath(im_75_qual)).st_size ) @unittest.skipUnless(PILBackend.available(), "PIL not available") @@ -123,7 +125,7 @@ def test_pil_file_deinterlace(self): from PIL import Image with Image.open(path) as img: - self.assertNotIn("progression", img.info) + assert "progression" not in img.info @unittest.skipUnless(IMBackend.available(), "ImageMagick not available") def test_im_file_deinterlace(self): @@ -140,7 +142,7 @@ def test_im_file_deinterlace(self): syspath(path, prefix=False), ] out = command_output(cmd).stdout - self.assertEqual(out, b"None") + assert out == b"None" @patch("beets.util.artresizer.util") def test_write_metadata_im(self, mock_util): diff --git a/test/test_autotag.py b/test/test_autotag.py index eefa360231..7e6e7f43e9 100644 --- a/test/test_autotag.py +++ b/test/test_autotag.py @@ -18,6 +18,8 @@ import re import unittest +import pytest + from beets import autotag, config from beets.autotag import AlbumInfo, TrackInfo, match from beets.autotag.hooks import Distance, string_dist @@ -30,23 +32,23 @@ class PluralityTest(BeetsTestCase): def test_plurality_consensus(self): objs = [1, 1, 1, 1] obj, freq = plurality(objs) - self.assertEqual(obj, 1) - self.assertEqual(freq, 4) + assert obj == 1 + assert freq == 4 def test_plurality_near_consensus(self): objs = [1, 1, 2, 1] obj, freq = plurality(objs) - self.assertEqual(obj, 1) - self.assertEqual(freq, 3) + assert obj == 1 + assert freq == 3 def test_plurality_conflict(self): objs = [1, 1, 2, 2, 3] obj, freq = plurality(objs) - self.assertIn(obj, (1, 2)) - self.assertEqual(freq, 2) + assert obj in (1, 2) + assert freq == 2 def test_plurality_empty_sequence_raises_error(self): - with self.assertRaises(ValueError): + with pytest.raises(ValueError): plurality([]) def test_current_metadata_finds_pluralities(self): @@ -56,9 +58,9 @@ def test_current_metadata_finds_pluralities(self): Item(artist="The Beatles", album="Teh White Album"), ] likelies, consensus = match.current_metadata(items) - self.assertEqual(likelies["artist"], "The Beatles") - self.assertEqual(likelies["album"], "The White Album") - self.assertFalse(consensus["artist"]) + assert likelies["artist"] == "The Beatles" + assert likelies["album"] == "The White Album" + assert not consensus["artist"] def test_current_metadata_artist_consensus(self): items = [ @@ -67,9 +69,9 @@ def test_current_metadata_artist_consensus(self): Item(artist="The Beatles", album="Teh White Album"), ] likelies, consensus = match.current_metadata(items) - self.assertEqual(likelies["artist"], "The Beatles") - self.assertEqual(likelies["album"], "The White Album") - self.assertTrue(consensus["artist"]) + assert likelies["artist"] == "The Beatles" + assert likelies["album"] == "The White Album" + assert consensus["artist"] def test_albumartist_consensus(self): items = [ @@ -78,8 +80,8 @@ def test_albumartist_consensus(self): Item(artist="tartist3", album="album", albumartist="aartist"), ] likelies, consensus = match.current_metadata(items) - self.assertEqual(likelies["artist"], "aartist") - self.assertFalse(consensus["artist"]) + assert likelies["artist"] == "aartist" + assert not consensus["artist"] def test_current_metadata_likelies(self): fields = [ @@ -96,16 +98,13 @@ def test_current_metadata_likelies(self): "media", "albumdisambig", ] - items = [ - Item(**{f: "{}_{}".format(f, i or 1) for f in fields}) - for i in range(5) - ] + items = [Item(**{f: f"{f}_{i or 1}" for f in fields}) for i in range(5)] likelies, _ = match.current_metadata(items) for f in fields: if isinstance(likelies[f], int): - self.assertEqual(likelies[f], 0) + assert likelies[f] == 0 else: - self.assertEqual(likelies[f], "%s_1" % f) + assert likelies[f] == f"{f}_1" def _make_item(title, track, artist="some artist"): @@ -154,91 +153,89 @@ def tearDown(self): def test_add(self): dist = Distance() dist.add("add", 1.0) - self.assertEqual(dist._penalties, {"add": [1.0]}) + assert dist._penalties == {"add": [1.0]} def test_add_equality(self): dist = Distance() dist.add_equality("equality", "ghi", ["abc", "def", "ghi"]) - self.assertEqual(dist._penalties["equality"], [0.0]) + assert dist._penalties["equality"] == [0.0] dist.add_equality("equality", "xyz", ["abc", "def", "ghi"]) - self.assertEqual(dist._penalties["equality"], [0.0, 1.0]) + assert dist._penalties["equality"] == [0.0, 1.0] dist.add_equality("equality", "abc", re.compile(r"ABC", re.I)) - self.assertEqual(dist._penalties["equality"], [0.0, 1.0, 0.0]) + assert dist._penalties["equality"] == [0.0, 1.0, 0.0] def test_add_expr(self): dist = Distance() dist.add_expr("expr", True) - self.assertEqual(dist._penalties["expr"], [1.0]) + assert dist._penalties["expr"] == [1.0] dist.add_expr("expr", False) - self.assertEqual(dist._penalties["expr"], [1.0, 0.0]) + assert dist._penalties["expr"] == [1.0, 0.0] def test_add_number(self): dist = Distance() # Add a full penalty for each number of difference between two numbers. dist.add_number("number", 1, 1) - self.assertEqual(dist._penalties["number"], [0.0]) + assert dist._penalties["number"] == [0.0] dist.add_number("number", 1, 2) - self.assertEqual(dist._penalties["number"], [0.0, 1.0]) + assert dist._penalties["number"] == [0.0, 1.0] dist.add_number("number", 2, 1) - self.assertEqual(dist._penalties["number"], [0.0, 1.0, 1.0]) + assert dist._penalties["number"] == [0.0, 1.0, 1.0] dist.add_number("number", -1, 2) - self.assertEqual( - dist._penalties["number"], [0.0, 1.0, 1.0, 1.0, 1.0, 1.0] - ) + assert dist._penalties["number"] == [0.0, 1.0, 1.0, 1.0, 1.0, 1.0] def test_add_priority(self): dist = Distance() dist.add_priority("priority", "abc", "abc") - self.assertEqual(dist._penalties["priority"], [0.0]) + assert dist._penalties["priority"] == [0.0] dist.add_priority("priority", "def", ["abc", "def"]) - self.assertEqual(dist._penalties["priority"], [0.0, 0.5]) + assert dist._penalties["priority"] == [0.0, 0.5] dist.add_priority( "priority", "gh", ["ab", "cd", "ef", re.compile("GH", re.I)] ) - self.assertEqual(dist._penalties["priority"], [0.0, 0.5, 0.75]) + assert dist._penalties["priority"] == [0.0, 0.5, 0.75] dist.add_priority("priority", "xyz", ["abc", "def"]) - self.assertEqual(dist._penalties["priority"], [0.0, 0.5, 0.75, 1.0]) + assert dist._penalties["priority"] == [0.0, 0.5, 0.75, 1.0] def test_add_ratio(self): dist = Distance() dist.add_ratio("ratio", 25, 100) - self.assertEqual(dist._penalties["ratio"], [0.25]) + assert dist._penalties["ratio"] == [0.25] dist.add_ratio("ratio", 10, 5) - self.assertEqual(dist._penalties["ratio"], [0.25, 1.0]) + assert dist._penalties["ratio"] == [0.25, 1.0] dist.add_ratio("ratio", -5, 5) - self.assertEqual(dist._penalties["ratio"], [0.25, 1.0, 0.0]) + assert dist._penalties["ratio"] == [0.25, 1.0, 0.0] dist.add_ratio("ratio", 5, 0) - self.assertEqual(dist._penalties["ratio"], [0.25, 1.0, 0.0, 0.0]) + assert dist._penalties["ratio"] == [0.25, 1.0, 0.0, 0.0] def test_add_string(self): dist = Distance() sdist = string_dist("abc", "bcd") dist.add_string("string", "abc", "bcd") - self.assertEqual(dist._penalties["string"], [sdist]) - self.assertNotEqual(dist._penalties["string"], [0]) + assert dist._penalties["string"] == [sdist] + assert dist._penalties["string"] != [0] def test_add_string_none(self): dist = Distance() dist.add_string("string", None, "string") - self.assertEqual(dist._penalties["string"], [1]) + assert dist._penalties["string"] == [1] def test_add_string_both_none(self): dist = Distance() dist.add_string("string", None, None) - self.assertEqual(dist._penalties["string"], [0]) + assert dist._penalties["string"] == [0] def test_distance(self): config["match"]["distance_weights"]["album"] = 2.0 @@ -249,11 +246,11 @@ def test_distance(self): dist.add("album", 0.5) dist.add("media", 0.25) dist.add("media", 0.75) - self.assertEqual(dist.distance, 0.5) + assert dist.distance == 0.5 # __getitem__() - self.assertEqual(dist["album"], 0.25) - self.assertEqual(dist["media"], 0.25) + assert dist["album"] == 0.25 + assert dist["media"] == 0.25 def test_max_distance(self): config["match"]["distance_weights"]["album"] = 3.0 @@ -264,7 +261,7 @@ def test_max_distance(self): dist.add("album", 0.5) dist.add("medium", 0.0) dist.add("medium", 0.0) - self.assertEqual(dist.max_distance, 5.0) + assert dist.max_distance == 5.0 def test_operators(self): config["match"]["distance_weights"]["source"] = 1.0 @@ -277,14 +274,14 @@ def test_operators(self): dist.add("album", 0.5) dist.add("medium", 0.25) dist.add("medium", 0.75) - self.assertEqual(len(dist), 2) - self.assertEqual(list(dist), [("album", 0.2), ("medium", 0.2)]) - self.assertEqual(dist, 0.4) - self.assertLess(dist, 1.0) - self.assertGreater(dist, 0.0) - self.assertEqual(dist - 0.4, 0.0) - self.assertEqual(0.4 - dist, 0.0) - self.assertEqual(float(dist), 0.4) + assert len(dist) == 2 + assert list(dist) == [("album", 0.2), ("medium", 0.2)] + assert dist == 0.4 + assert dist < 1.0 + assert dist > 0.0 + assert dist - 0.4 == 0.0 + assert 0.4 - dist == 0.0 + assert float(dist) == 0.4 def test_raw_distance(self): config["match"]["distance_weights"]["album"] = 3.0 @@ -295,7 +292,7 @@ def test_raw_distance(self): dist.add("album", 0.5) dist.add("medium", 0.25) dist.add("medium", 0.5) - self.assertEqual(dist.raw_distance, 2.25) + assert dist.raw_distance == 2.25 def test_items(self): config["match"]["distance_weights"]["album"] = 4.0 @@ -305,13 +302,13 @@ def test_items(self): dist = Distance() dist.add("album", 0.1875) dist.add("medium", 0.75) - self.assertEqual(dist.items(), [("medium", 0.25), ("album", 0.125)]) + assert dist.items() == [("medium", 0.25), ("album", 0.125)] # Sort by key if distance is equal. dist = Distance() dist.add("album", 0.375) dist.add("medium", 0.75) - self.assertEqual(dist.items(), [("album", 0.25), ("medium", 0.25)]) + assert dist.items() == [("album", 0.25), ("medium", 0.25)] def test_update(self): dist1 = Distance() @@ -325,9 +322,10 @@ def test_update(self): dist1.update(dist2) - self.assertEqual( - dist1._penalties, {"album": [0.5, 0.75, 0.25], "media": [1.0, 0.05]} - ) + assert dist1._penalties == { + "album": [0.5, 0.75, 0.25], + "media": [1.0, 0.05], + } class TrackDistanceTest(BeetsTestCase): @@ -335,27 +333,27 @@ def test_identical_tracks(self): item = _make_item("one", 1) info = _make_trackinfo()[0] dist = match.track_distance(item, info, incl_artist=True) - self.assertEqual(dist, 0.0) + assert dist == 0.0 def test_different_title(self): item = _make_item("foo", 1) info = _make_trackinfo()[0] dist = match.track_distance(item, info, incl_artist=True) - self.assertNotEqual(dist, 0.0) + assert dist != 0.0 def test_different_artist(self): item = _make_item("one", 1) item.artist = "foo" info = _make_trackinfo()[0] dist = match.track_distance(item, info, incl_artist=True) - self.assertNotEqual(dist, 0.0) + assert dist != 0.0 def test_various_artists_tolerated(self): item = _make_item("one", 1) item.artist = "Various Artists" info = _make_trackinfo()[0] dist = match.track_distance(item, info, incl_artist=True) - self.assertEqual(dist, 0.0) + assert dist == 0.0 class AlbumDistanceTest(BeetsTestCase): @@ -379,7 +377,7 @@ def test_identical_albums(self): tracks=_make_trackinfo(), va=False, ) - self.assertEqual(self._dist(items, info), 0) + assert self._dist(items, info) == 0 def test_incomplete_album(self): items = [] @@ -392,9 +390,9 @@ def test_incomplete_album(self): va=False, ) dist = self._dist(items, info) - self.assertNotEqual(dist, 0) + assert dist != 0 # Make sure the distance is not too great - self.assertLess(dist, 0.2) + assert dist < 0.2 def test_global_artists_differ(self): items = [] @@ -407,7 +405,7 @@ def test_global_artists_differ(self): tracks=_make_trackinfo(), va=False, ) - self.assertNotEqual(self._dist(items, info), 0) + assert self._dist(items, info) != 0 def test_comp_track_artists_match(self): items = [] @@ -420,7 +418,7 @@ def test_comp_track_artists_match(self): tracks=_make_trackinfo(), va=True, ) - self.assertEqual(self._dist(items, info), 0) + assert self._dist(items, info) == 0 def test_comp_no_track_artists(self): # Some VA releases don't have track artists (incomplete metadata). @@ -437,7 +435,7 @@ def test_comp_no_track_artists(self): info.tracks[0].artist = None info.tracks[1].artist = None info.tracks[2].artist = None - self.assertEqual(self._dist(items, info), 0) + assert self._dist(items, info) == 0 def test_comp_track_artists_do_not_match(self): items = [] @@ -450,7 +448,7 @@ def test_comp_track_artists_do_not_match(self): tracks=_make_trackinfo(), va=True, ) - self.assertNotEqual(self._dist(items, info), 0) + assert self._dist(items, info) != 0 def test_tracks_out_of_order(self): items = [] @@ -464,7 +462,7 @@ def test_tracks_out_of_order(self): va=False, ) dist = self._dist(items, info) - self.assertTrue(0 < dist < 0.2) + assert 0 < dist < 0.2 def test_two_medium_release(self): items = [] @@ -481,7 +479,7 @@ def test_two_medium_release(self): info.tracks[1].medium_index = 2 info.tracks[2].medium_index = 1 dist = self._dist(items, info) - self.assertEqual(dist, 0) + assert dist == 0 def test_per_medium_track_numbers(self): items = [] @@ -498,7 +496,7 @@ def test_per_medium_track_numbers(self): info.tracks[1].medium_index = 2 info.tracks[2].medium_index = 1 dist = self._dist(items, info) - self.assertEqual(dist, 0) + assert dist == 0 class AssignmentTest(unittest.TestCase): @@ -523,16 +521,13 @@ def test_reorder_when_track_numbers_incorrect(self): mapping, extra_items, extra_tracks = match.assign_items( items, trackinfo ) - self.assertEqual(extra_items, []) - self.assertEqual(extra_tracks, []) - self.assertEqual( - mapping, - { - items[0]: trackinfo[0], - items[1]: trackinfo[2], - items[2]: trackinfo[1], - }, - ) + assert extra_items == [] + assert extra_tracks == [] + assert mapping == { + items[0]: trackinfo[0], + items[1]: trackinfo[2], + items[2]: trackinfo[1], + } def test_order_works_with_invalid_track_numbers(self): items = [] @@ -546,16 +541,13 @@ def test_order_works_with_invalid_track_numbers(self): mapping, extra_items, extra_tracks = match.assign_items( items, trackinfo ) - self.assertEqual(extra_items, []) - self.assertEqual(extra_tracks, []) - self.assertEqual( - mapping, - { - items[0]: trackinfo[0], - items[1]: trackinfo[2], - items[2]: trackinfo[1], - }, - ) + assert extra_items == [] + assert extra_tracks == [] + assert mapping == { + items[0]: trackinfo[0], + items[1]: trackinfo[2], + items[2]: trackinfo[1], + } def test_order_works_with_missing_tracks(self): items = [] @@ -568,15 +560,9 @@ def test_order_works_with_missing_tracks(self): mapping, extra_items, extra_tracks = match.assign_items( items, trackinfo ) - self.assertEqual(extra_items, []) - self.assertEqual(extra_tracks, [trackinfo[1]]) - self.assertEqual( - mapping, - { - items[0]: trackinfo[0], - items[1]: trackinfo[2], - }, - ) + assert extra_items == [] + assert extra_tracks == [trackinfo[1]] + assert mapping == {items[0]: trackinfo[0], items[1]: trackinfo[2]} def test_order_works_with_extra_tracks(self): items = [] @@ -589,15 +575,9 @@ def test_order_works_with_extra_tracks(self): mapping, extra_items, extra_tracks = match.assign_items( items, trackinfo ) - self.assertEqual(extra_items, [items[1]]) - self.assertEqual(extra_tracks, []) - self.assertEqual( - mapping, - { - items[0]: trackinfo[0], - items[2]: trackinfo[1], - }, - ) + assert extra_items == [items[1]] + assert extra_tracks == [] + assert mapping == {items[0]: trackinfo[0], items[2]: trackinfo[1]} def test_order_works_when_track_names_are_entirely_wrong(self): # A real-world test case contributed by a user. @@ -647,10 +627,10 @@ def info(index, title, length): mapping, extra_items, extra_tracks = match.assign_items( items, trackinfo ) - self.assertEqual(extra_items, []) - self.assertEqual(extra_tracks, []) + assert extra_items == [] + assert extra_tracks == [] for item, info in mapping.items(): - self.assertEqual(items.index(item), trackinfo.index(info)) + assert items.index(item) == trackinfo.index(info) class ApplyTestUtil: @@ -718,118 +698,107 @@ def setUp(self): def test_titles_applied(self): self._apply() - self.assertEqual(self.items[0].title, "oneNew") - self.assertEqual(self.items[1].title, "twoNew") + assert self.items[0].title == "oneNew" + assert self.items[1].title == "twoNew" def test_album_and_artist_applied_to_all(self): self._apply() - self.assertEqual(self.items[0].album, "albumNew") - self.assertEqual(self.items[1].album, "albumNew") - self.assertEqual(self.items[0].artist, "artistNew") - self.assertEqual(self.items[1].artist, "artistNew") - self.assertEqual(self.items[0].artists, ["artistNew", "artistNew2"]) - self.assertEqual(self.items[1].artists, ["artistNew", "artistNew2"]) - self.assertEqual( - self.items[0].albumartists, ["artistNew", "artistNew2"] - ) - self.assertEqual( - self.items[1].albumartists, ["artistNew", "artistNew2"] - ) + assert self.items[0].album == "albumNew" + assert self.items[1].album == "albumNew" + assert self.items[0].artist == "artistNew" + assert self.items[1].artist == "artistNew" + assert self.items[0].artists == ["artistNew", "artistNew2"] + assert self.items[1].artists == ["artistNew", "artistNew2"] + assert self.items[0].albumartists == ["artistNew", "artistNew2"] + assert self.items[1].albumartists == ["artistNew", "artistNew2"] def test_track_index_applied(self): self._apply() - self.assertEqual(self.items[0].track, 1) - self.assertEqual(self.items[1].track, 2) + assert self.items[0].track == 1 + assert self.items[1].track == 2 def test_track_total_applied(self): self._apply() - self.assertEqual(self.items[0].tracktotal, 2) - self.assertEqual(self.items[1].tracktotal, 2) + assert self.items[0].tracktotal == 2 + assert self.items[1].tracktotal == 2 def test_disc_index_applied(self): self._apply() - self.assertEqual(self.items[0].disc, 1) - self.assertEqual(self.items[1].disc, 2) + assert self.items[0].disc == 1 + assert self.items[1].disc == 2 def test_disc_total_applied(self): self._apply() - self.assertEqual(self.items[0].disctotal, 2) - self.assertEqual(self.items[1].disctotal, 2) + assert self.items[0].disctotal == 2 + assert self.items[1].disctotal == 2 def test_per_disc_numbering(self): self._apply(per_disc_numbering=True) - self.assertEqual(self.items[0].track, 1) - self.assertEqual(self.items[1].track, 1) + assert self.items[0].track == 1 + assert self.items[1].track == 1 def test_per_disc_numbering_track_total(self): self._apply(per_disc_numbering=True) - self.assertEqual(self.items[0].tracktotal, 1) - self.assertEqual(self.items[1].tracktotal, 1) + assert self.items[0].tracktotal == 1 + assert self.items[1].tracktotal == 1 def test_artist_credit(self): self._apply(artist_credit=True) - self.assertEqual(self.items[0].artist, "trackArtistCredit") - self.assertEqual(self.items[1].artist, "albumArtistCredit") - self.assertEqual(self.items[0].albumartist, "albumArtistCredit") - self.assertEqual(self.items[1].albumartist, "albumArtistCredit") - self.assertEqual( - self.items[0].albumartists, - ["albumArtistCredit", "albumArtistCredit2"], - ) - self.assertEqual( - self.items[1].albumartists, - ["albumArtistCredit", "albumArtistCredit2"], - ) + assert self.items[0].artist == "trackArtistCredit" + assert self.items[1].artist == "albumArtistCredit" + assert self.items[0].albumartist == "albumArtistCredit" + assert self.items[1].albumartist == "albumArtistCredit" + assert self.items[0].albumartists == [ + "albumArtistCredit", + "albumArtistCredit2", + ] + assert self.items[1].albumartists == [ + "albumArtistCredit", + "albumArtistCredit2", + ] def test_artist_credit_prefers_artist_over_albumartist_credit(self): self.info.tracks[0].artist = "oldArtist" self.info.tracks[0].artist_credit = None self._apply(artist_credit=True) - self.assertEqual(self.items[0].artist, "oldArtist") + assert self.items[0].artist == "oldArtist" def test_artist_credit_falls_back_to_albumartist(self): self.info.artist_credit = None self._apply(artist_credit=True) - self.assertEqual(self.items[1].artist, "artistNew") + assert self.items[1].artist == "artistNew" def test_mb_trackid_applied(self): self._apply() - self.assertEqual( - self.items[0].mb_trackid, "dfa939ec-118c-4d0f-84a0-60f3d1e6522c" + assert ( + self.items[0].mb_trackid == "dfa939ec-118c-4d0f-84a0-60f3d1e6522c" ) - self.assertEqual( - self.items[1].mb_trackid, "40130ed1-a27c-42fd-a328-1ebefb6caef4" + assert ( + self.items[1].mb_trackid == "40130ed1-a27c-42fd-a328-1ebefb6caef4" ) def test_mb_albumid_and_artistid_applied(self): self._apply() for item in self.items: - self.assertEqual( - item.mb_albumid, "7edb51cb-77d6-4416-a23c-3a8c2994a2c7" - ) - self.assertEqual( - item.mb_artistid, "a6623d39-2d8e-4f70-8242-0a9553b91e50" - ) - self.assertEqual( - item.mb_artistids, - [ - "a6623d39-2d8e-4f70-8242-0a9553b91e50", - "a6623d39-2d8e-4f70-8242-0a9553b91e51", - ], - ) + assert item.mb_albumid == "7edb51cb-77d6-4416-a23c-3a8c2994a2c7" + assert item.mb_artistid == "a6623d39-2d8e-4f70-8242-0a9553b91e50" + assert item.mb_artistids == [ + "a6623d39-2d8e-4f70-8242-0a9553b91e50", + "a6623d39-2d8e-4f70-8242-0a9553b91e51", + ] def test_albumtype_applied(self): self._apply() - self.assertEqual(self.items[0].albumtype, "album") - self.assertEqual(self.items[1].albumtype, "album") + assert self.items[0].albumtype == "album" + assert self.items[1].albumtype == "album" def test_album_artist_overrides_empty_track_artist(self): my_info = self.info.copy() self._apply(info=my_info) - self.assertEqual(self.items[0].artist, "artistNew") - self.assertEqual(self.items[1].artist, "artistNew") - self.assertEqual(self.items[0].artists, ["artistNew", "artistNew2"]) - self.assertEqual(self.items[1].artists, ["artistNew", "artistNew2"]) + assert self.items[0].artist == "artistNew" + assert self.items[1].artist == "artistNew" + assert self.items[0].artists == ["artistNew", "artistNew2"] + assert self.items[1].artists == ["artistNew", "artistNew2"] def test_album_artist_overridden_by_nonempty_track_artist(self): my_info = self.info.copy() @@ -838,49 +807,50 @@ def test_album_artist_overridden_by_nonempty_track_artist(self): my_info.tracks[0].artists = ["artist1!", "artist1!!"] my_info.tracks[1].artists = ["artist2!", "artist2!!"] self._apply(info=my_info) - self.assertEqual(self.items[0].artist, "artist1!") - self.assertEqual(self.items[1].artist, "artist2!") - self.assertEqual(self.items[0].artists, ["artist1!", "artist1!!"]) - self.assertEqual(self.items[1].artists, ["artist2!", "artist2!!"]) + assert self.items[0].artist == "artist1!" + assert self.items[1].artist == "artist2!" + assert self.items[0].artists == ["artist1!", "artist1!!"] + assert self.items[1].artists == ["artist2!", "artist2!!"] def test_artist_credit_applied(self): self._apply() - self.assertEqual(self.items[0].albumartist_credit, "albumArtistCredit") - self.assertEqual( - self.items[0].albumartists_credit, - ["albumArtistCredit", "albumArtistCredit2"], - ) - self.assertEqual(self.items[0].artist_credit, "trackArtistCredit") - self.assertEqual(self.items[0].artists_credit, ["trackArtistCredit"]) - self.assertEqual(self.items[1].albumartist_credit, "albumArtistCredit") - self.assertEqual( - self.items[1].albumartists_credit, - ["albumArtistCredit", "albumArtistCredit2"], - ) - self.assertEqual(self.items[1].artist_credit, "albumArtistCredit") - self.assertEqual( - self.items[1].artists_credit, - ["albumArtistCredit", "albumArtistCredit2"], - ) + assert self.items[0].albumartist_credit == "albumArtistCredit" + assert self.items[0].albumartists_credit == [ + "albumArtistCredit", + "albumArtistCredit2", + ] + assert self.items[0].artist_credit == "trackArtistCredit" + assert self.items[0].artists_credit == ["trackArtistCredit"] + assert self.items[1].albumartist_credit == "albumArtistCredit" + assert self.items[1].albumartists_credit == [ + "albumArtistCredit", + "albumArtistCredit2", + ] + assert self.items[1].artist_credit == "albumArtistCredit" + assert self.items[1].artists_credit == [ + "albumArtistCredit", + "albumArtistCredit2", + ] def test_artist_sort_applied(self): self._apply() - self.assertEqual(self.items[0].albumartist_sort, "albumArtistSort") - self.assertEqual( - self.items[0].albumartists_sort, - ["albumArtistSort", "albumArtistSort2"], - ) - self.assertEqual(self.items[0].artist_sort, "trackArtistSort") - self.assertEqual(self.items[0].artists_sort, ["trackArtistSort"]) - self.assertEqual(self.items[1].albumartist_sort, "albumArtistSort") - self.assertEqual( - self.items[1].albumartists_sort, - ["albumArtistSort", "albumArtistSort2"], - ) - self.assertEqual(self.items[1].artist_sort, "albumArtistSort") - self.assertEqual( - self.items[1].artists_sort, ["albumArtistSort", "albumArtistSort2"] - ) + assert self.items[0].albumartist_sort == "albumArtistSort" + assert self.items[0].albumartists_sort == [ + "albumArtistSort", + "albumArtistSort2", + ] + assert self.items[0].artist_sort == "trackArtistSort" + assert self.items[0].artists_sort == ["trackArtistSort"] + assert self.items[1].albumartist_sort == "albumArtistSort" + assert self.items[1].albumartists_sort == [ + "albumArtistSort", + "albumArtistSort2", + ] + assert self.items[1].artist_sort == "albumArtistSort" + assert self.items[1].artists_sort == [ + "albumArtistSort", + "albumArtistSort2", + ] def test_full_date_applied(self): my_info = self.info.copy() @@ -889,9 +859,9 @@ def test_full_date_applied(self): my_info.day = 18 self._apply(info=my_info) - self.assertEqual(self.items[0].year, 2013) - self.assertEqual(self.items[0].month, 12) - self.assertEqual(self.items[0].day, 18) + assert self.items[0].year == 2013 + assert self.items[0].month == 12 + assert self.items[0].day == 18 def test_date_only_zeros_month_and_day(self): self.items = [] @@ -902,9 +872,9 @@ def test_date_only_zeros_month_and_day(self): my_info.year = 2013 self._apply(info=my_info) - self.assertEqual(self.items[0].year, 2013) - self.assertEqual(self.items[0].month, 0) - self.assertEqual(self.items[0].day, 0) + assert self.items[0].year == 2013 + assert self.items[0].month == 0 + assert self.items[0].day == 0 def test_missing_date_applies_nothing(self): self.items = [] @@ -913,16 +883,16 @@ def test_missing_date_applies_nothing(self): self._apply() - self.assertEqual(self.items[0].year, 1) - self.assertEqual(self.items[0].month, 2) - self.assertEqual(self.items[0].day, 3) + assert self.items[0].year == 1 + assert self.items[0].month == 2 + assert self.items[0].day == 3 def test_data_source_applied(self): my_info = self.info.copy() my_info.data_source = "MusicBrainz" self._apply(info=my_info) - self.assertEqual(self.items[0].data_source, "MusicBrainz") + assert self.items[0].data_source == "MusicBrainz" class ApplyCompilationTest(BeetsTestCase, ApplyTestUtil): @@ -962,97 +932,97 @@ def setUp(self): def test_album_and_track_artists_separate(self): self._apply() - self.assertEqual(self.items[0].artist, "artistOneNew") - self.assertEqual(self.items[1].artist, "artistTwoNew") - self.assertEqual(self.items[0].albumartist, "variousNew") - self.assertEqual(self.items[1].albumartist, "variousNew") + assert self.items[0].artist == "artistOneNew" + assert self.items[1].artist == "artistTwoNew" + assert self.items[0].albumartist == "variousNew" + assert self.items[1].albumartist == "variousNew" def test_mb_albumartistid_applied(self): self._apply() - self.assertEqual( - self.items[0].mb_albumartistid, - "89ad4ac3-39f7-470e-963a-56509c546377", + assert ( + self.items[0].mb_albumartistid + == "89ad4ac3-39f7-470e-963a-56509c546377" ) - self.assertEqual( - self.items[1].mb_albumartistid, - "89ad4ac3-39f7-470e-963a-56509c546377", + assert ( + self.items[1].mb_albumartistid + == "89ad4ac3-39f7-470e-963a-56509c546377" ) - self.assertEqual( - self.items[0].mb_artistid, "a05686fc-9db2-4c23-b99e-77f5db3e5282" + assert ( + self.items[0].mb_artistid == "a05686fc-9db2-4c23-b99e-77f5db3e5282" ) - self.assertEqual( - self.items[1].mb_artistid, "80b3cf5e-18fe-4c59-98c7-e5bb87210710" + assert ( + self.items[1].mb_artistid == "80b3cf5e-18fe-4c59-98c7-e5bb87210710" ) def test_va_flag_cleared_does_not_set_comp(self): self._apply() - self.assertFalse(self.items[0].comp) - self.assertFalse(self.items[1].comp) + assert not self.items[0].comp + assert not self.items[1].comp def test_va_flag_sets_comp(self): va_info = self.info.copy() va_info.va = True self._apply(info=va_info) - self.assertTrue(self.items[0].comp) - self.assertTrue(self.items[1].comp) + assert self.items[0].comp + assert self.items[1].comp class StringDistanceTest(unittest.TestCase): def test_equal_strings(self): dist = string_dist("Some String", "Some String") - self.assertEqual(dist, 0.0) + assert dist == 0.0 def test_different_strings(self): dist = string_dist("Some String", "Totally Different") - self.assertNotEqual(dist, 0.0) + assert dist != 0.0 def test_punctuation_ignored(self): dist = string_dist("Some String", "Some.String!") - self.assertEqual(dist, 0.0) + assert dist == 0.0 def test_case_ignored(self): dist = string_dist("Some String", "sOME sTring") - self.assertEqual(dist, 0.0) + assert dist == 0.0 def test_leading_the_has_lower_weight(self): dist1 = string_dist("XXX Band Name", "Band Name") dist2 = string_dist("The Band Name", "Band Name") - self.assertLess(dist2, dist1) + assert dist2 < dist1 def test_parens_have_lower_weight(self): dist1 = string_dist("One .Two.", "One") dist2 = string_dist("One (Two)", "One") - self.assertLess(dist2, dist1) + assert dist2 < dist1 def test_brackets_have_lower_weight(self): dist1 = string_dist("One .Two.", "One") dist2 = string_dist("One [Two]", "One") - self.assertLess(dist2, dist1) + assert dist2 < dist1 def test_ep_label_has_zero_weight(self): dist = string_dist("My Song (EP)", "My Song") - self.assertEqual(dist, 0.0) + assert dist == 0.0 def test_featured_has_lower_weight(self): dist1 = string_dist("My Song blah Someone", "My Song") dist2 = string_dist("My Song feat Someone", "My Song") - self.assertLess(dist2, dist1) + assert dist2 < dist1 def test_postfix_the(self): dist = string_dist("The Song Title", "Song Title, The") - self.assertEqual(dist, 0.0) + assert dist == 0.0 def test_postfix_a(self): dist = string_dist("A Song Title", "Song Title, A") - self.assertEqual(dist, 0.0) + assert dist == 0.0 def test_postfix_an(self): dist = string_dist("An Album Title", "Album Title, An") - self.assertEqual(dist, 0.0) + assert dist == 0.0 def test_empty_strings(self): dist = string_dist("", "") - self.assertEqual(dist, 0.0) + assert dist == 0.0 def test_solo_pattern(self): # Just make sure these don't crash. @@ -1062,15 +1032,15 @@ def test_solo_pattern(self): def test_heuristic_does_not_harm_distance(self): dist = string_dist("Untitled", "[Untitled]") - self.assertEqual(dist, 0.0) + assert dist == 0.0 def test_ampersand_expansion(self): dist = string_dist("And", "&") - self.assertEqual(dist, 0.0) + assert dist == 0.0 def test_accented_characters(self): dist = string_dist("\xe9\xe1\xf1", "ean") - self.assertEqual(dist, 0.0) + assert dist == 0.0 class EnumTest(BeetsTestCase): @@ -1082,9 +1052,9 @@ def test_ordered_enum(self): OrderedEnumClass = match.OrderedEnum( # noqa "OrderedEnumTest", ["a", "b", "c"] ) - self.assertLess(OrderedEnumClass.a, OrderedEnumClass.b) - self.assertLess(OrderedEnumClass.a, OrderedEnumClass.c) - self.assertLess(OrderedEnumClass.b, OrderedEnumClass.c) - self.assertGreater(OrderedEnumClass.b, OrderedEnumClass.a) - self.assertGreater(OrderedEnumClass.c, OrderedEnumClass.a) - self.assertGreater(OrderedEnumClass.c, OrderedEnumClass.b) + assert OrderedEnumClass.a < OrderedEnumClass.b + assert OrderedEnumClass.a < OrderedEnumClass.c + assert OrderedEnumClass.b < OrderedEnumClass.c + assert OrderedEnumClass.b > OrderedEnumClass.a + assert OrderedEnumClass.c > OrderedEnumClass.a + assert OrderedEnumClass.c > OrderedEnumClass.b diff --git a/test/test_config_command.py b/test/test_config_command.py index 980ef93a24..388b649737 100644 --- a/test/test_config_command.py +++ b/test/test_config_command.py @@ -1,6 +1,7 @@ import os from unittest.mock import patch +import pytest import yaml from beets import config, ui @@ -37,52 +38,52 @@ def _run_with_yaml_output(self, *args): def test_show_user_config(self): output = self._run_with_yaml_output("config", "-c") - self.assertEqual(output["option"], "value") - self.assertEqual(output["password"], "password_value") + assert output["option"] == "value" + assert output["password"] == "password_value" def test_show_user_config_with_defaults(self): output = self._run_with_yaml_output("config", "-dc") - self.assertEqual(output["option"], "value") - self.assertEqual(output["password"], "password_value") - self.assertEqual(output["library"], "lib") - self.assertFalse(output["import"]["timid"]) + assert output["option"] == "value" + assert output["password"] == "password_value" + assert output["library"] == "lib" + assert not output["import"]["timid"] def test_show_user_config_with_cli(self): output = self._run_with_yaml_output( "--config", self.cli_config_path, "config" ) - self.assertEqual(output["library"], "lib") - self.assertEqual(output["option"], "cli overwrite") + assert output["library"] == "lib" + assert output["option"] == "cli overwrite" def test_show_redacted_user_config(self): output = self._run_with_yaml_output("config") - self.assertEqual(output["option"], "value") - self.assertEqual(output["password"], "REDACTED") + assert output["option"] == "value" + assert output["password"] == "REDACTED" def test_show_redacted_user_config_with_defaults(self): output = self._run_with_yaml_output("config", "-d") - self.assertEqual(output["option"], "value") - self.assertEqual(output["password"], "REDACTED") - self.assertFalse(output["import"]["timid"]) + assert output["option"] == "value" + assert output["password"] == "REDACTED" + assert not output["import"]["timid"] def test_config_paths(self): output = self.run_with_output("config", "-p") paths = output.split("\n") - self.assertEqual(len(paths), 2) - self.assertEqual(paths[0], self.config_path) + assert len(paths) == 2 + assert paths[0] == self.config_path def test_config_paths_with_cli(self): output = self.run_with_output( "--config", self.cli_config_path, "config", "-p" ) paths = output.split("\n") - self.assertEqual(len(paths), 3) - self.assertEqual(paths[0], self.cli_config_path) + assert len(paths) == 3 + assert paths[0] == self.cli_config_path def test_edit_config_with_visual_or_editor_env(self): os.environ["EDITOR"] = "myeditor" @@ -110,12 +111,11 @@ def test_edit_config_with_automatic_open(self): ) def test_config_editor_not_found(self): - with self.assertRaises(ui.UserError) as user_error: + msg_match = "Could not edit configuration.*here is problem" + with pytest.raises(ui.UserError, match=msg_match): with patch("os.execlp") as execlp: execlp.side_effect = OSError("here is problem") self.run_command("config", "-e") - self.assertIn("Could not edit configuration", str(user_error.exception)) - self.assertIn("here is problem", str(user_error.exception)) def test_edit_invalid_config_file(self): with open(self.config_path, "w") as file: diff --git a/test/test_datequery.py b/test/test_datequery.py index 55fdf619ba..31ec5f9da7 100644 --- a/test/test_datequery.py +++ b/test/test_datequery.py @@ -19,6 +19,8 @@ import unittest from datetime import datetime, timedelta +import pytest + from beets.dbcore.query import ( DateInterval, DateQuery, @@ -139,13 +141,13 @@ def assertContains( # noqa date = _date(date_pattern) (start, end) = _parse_periods(interval_pattern) interval = DateInterval.from_periods(start, end) - self.assertTrue(interval.contains(date)) + assert interval.contains(date) def assertExcludes(self, interval_pattern, date_pattern): # noqa date = _date(date_pattern) (start, end) = _parse_periods(interval_pattern) interval = DateInterval.from_periods(start, end) - self.assertFalse(interval.contains(date)) + assert not interval.contains(date) def _parsetime(s): @@ -161,30 +163,30 @@ def setUp(self): def test_single_month_match_fast(self): query = DateQuery("added", "2013-03") matched = self.lib.items(query) - self.assertEqual(len(matched), 1) + assert len(matched) == 1 def test_single_month_nonmatch_fast(self): query = DateQuery("added", "2013-04") matched = self.lib.items(query) - self.assertEqual(len(matched), 0) + assert len(matched) == 0 def test_single_month_match_slow(self): query = DateQuery("added", "2013-03") - self.assertTrue(query.match(self.i)) + assert query.match(self.i) def test_single_month_nonmatch_slow(self): query = DateQuery("added", "2013-04") - self.assertFalse(query.match(self.i)) + assert not query.match(self.i) def test_single_day_match_fast(self): query = DateQuery("added", "2013-03-30") matched = self.lib.items(query) - self.assertEqual(len(matched), 1) + assert len(matched) == 1 def test_single_day_nonmatch_fast(self): query = DateQuery("added", "2013-03-31") matched = self.lib.items(query) - self.assertEqual(len(matched), 0) + assert len(matched) == 0 class DateQueryTestRelative(ItemInDBTestCase): @@ -201,36 +203,36 @@ def setUp(self): def test_single_month_match_fast(self): query = DateQuery("added", self._now.strftime("%Y-%m")) matched = self.lib.items(query) - self.assertEqual(len(matched), 1) + assert len(matched) == 1 def test_single_month_nonmatch_fast(self): query = DateQuery( "added", (self._now + timedelta(days=30)).strftime("%Y-%m") ) matched = self.lib.items(query) - self.assertEqual(len(matched), 0) + assert len(matched) == 0 def test_single_month_match_slow(self): query = DateQuery("added", self._now.strftime("%Y-%m")) - self.assertTrue(query.match(self.i)) + assert query.match(self.i) def test_single_month_nonmatch_slow(self): query = DateQuery( "added", (self._now + timedelta(days=30)).strftime("%Y-%m") ) - self.assertFalse(query.match(self.i)) + assert not query.match(self.i) def test_single_day_match_fast(self): query = DateQuery("added", self._now.strftime("%Y-%m-%d")) matched = self.lib.items(query) - self.assertEqual(len(matched), 1) + assert len(matched) == 1 def test_single_day_nonmatch_fast(self): query = DateQuery( "added", (self._now + timedelta(days=1)).strftime("%Y-%m-%d") ) matched = self.lib.items(query) - self.assertEqual(len(matched), 0) + assert len(matched) == 0 class DateQueryTestRelativeMore(ItemInDBTestCase): @@ -243,46 +245,46 @@ def test_relative(self): for timespan in ["d", "w", "m", "y"]: query = DateQuery("added", "-4" + timespan + "..+4" + timespan) matched = self.lib.items(query) - self.assertEqual(len(matched), 1) + assert len(matched) == 1 def test_relative_fail(self): for timespan in ["d", "w", "m", "y"]: query = DateQuery("added", "-2" + timespan + "..-1" + timespan) matched = self.lib.items(query) - self.assertEqual(len(matched), 0) + assert len(matched) == 0 def test_start_relative(self): for timespan in ["d", "w", "m", "y"]: query = DateQuery("added", "-4" + timespan + "..") matched = self.lib.items(query) - self.assertEqual(len(matched), 1) + assert len(matched) == 1 def test_start_relative_fail(self): for timespan in ["d", "w", "m", "y"]: query = DateQuery("added", "4" + timespan + "..") matched = self.lib.items(query) - self.assertEqual(len(matched), 0) + assert len(matched) == 0 def test_end_relative(self): for timespan in ["d", "w", "m", "y"]: query = DateQuery("added", "..+4" + timespan) matched = self.lib.items(query) - self.assertEqual(len(matched), 1) + assert len(matched) == 1 def test_end_relative_fail(self): for timespan in ["d", "w", "m", "y"]: query = DateQuery("added", "..-4" + timespan) matched = self.lib.items(query) - self.assertEqual(len(matched), 0) + assert len(matched) == 0 class DateQueryConstructTest(unittest.TestCase): def test_long_numbers(self): - with self.assertRaises(InvalidQueryArgumentValueError): + with pytest.raises(InvalidQueryArgumentValueError): DateQuery("added", "1409830085..1412422089") def test_too_many_components(self): - with self.assertRaises(InvalidQueryArgumentValueError): + with pytest.raises(InvalidQueryArgumentValueError): DateQuery("added", "12-34-56-78") def test_invalid_date_query(self): @@ -297,24 +299,24 @@ def test_invalid_date_query(self): "..2aa", ] for q in q_list: - with self.assertRaises(InvalidQueryArgumentValueError): + with pytest.raises(InvalidQueryArgumentValueError): DateQuery("added", q) def test_datetime_uppercase_t_separator(self): date_query = DateQuery("added", "2000-01-01T12") - self.assertEqual(date_query.interval.start, datetime(2000, 1, 1, 12)) - self.assertEqual(date_query.interval.end, datetime(2000, 1, 1, 13)) + assert date_query.interval.start == datetime(2000, 1, 1, 12) + assert date_query.interval.end == datetime(2000, 1, 1, 13) def test_datetime_lowercase_t_separator(self): date_query = DateQuery("added", "2000-01-01t12") - self.assertEqual(date_query.interval.start, datetime(2000, 1, 1, 12)) - self.assertEqual(date_query.interval.end, datetime(2000, 1, 1, 13)) + assert date_query.interval.start == datetime(2000, 1, 1, 12) + assert date_query.interval.end == datetime(2000, 1, 1, 13) def test_datetime_space_separator(self): date_query = DateQuery("added", "2000-01-01 12") - self.assertEqual(date_query.interval.start, datetime(2000, 1, 1, 12)) - self.assertEqual(date_query.interval.end, datetime(2000, 1, 1, 13)) + assert date_query.interval.start == datetime(2000, 1, 1, 12) + assert date_query.interval.end == datetime(2000, 1, 1, 13) def test_datetime_invalid_separator(self): - with self.assertRaises(InvalidQueryArgumentValueError): + with pytest.raises(InvalidQueryArgumentValueError): DateQuery("added", "2000-01-01x12") diff --git a/test/test_dbcore.py b/test/test_dbcore.py index 803612d44c..fc4a614f77 100644 --- a/test/test_dbcore.py +++ b/test/test_dbcore.py @@ -20,6 +20,8 @@ import unittest from tempfile import mkstemp +import pytest + from beets import dbcore from beets.test import _common @@ -190,7 +192,7 @@ def test_open_with_same_fields_leaves_untouched(self): c.execute("select * from test") row = c.fetchone() c.connection.close() - self.assertEqual(len(row.keys()), len(ModelFixture2._fields)) + assert len(row.keys()) == len(ModelFixture2._fields) def test_open_with_new_field_adds_column(self): new_lib = DatabaseFixture3(self.libfile) @@ -198,7 +200,7 @@ def test_open_with_new_field_adds_column(self): c.execute("select * from test") row = c.fetchone() c.connection.close() - self.assertEqual(len(row.keys()), len(ModelFixture3._fields)) + assert len(row.keys()) == len(ModelFixture3._fields) def test_open_with_fewer_fields_leaves_untouched(self): new_lib = DatabaseFixture1(self.libfile) @@ -206,7 +208,7 @@ def test_open_with_fewer_fields_leaves_untouched(self): c.execute("select * from test") row = c.fetchone() c.connection.close() - self.assertEqual(len(row.keys()), len(ModelFixture2._fields)) + assert len(row.keys()) == len(ModelFixture2._fields) def test_open_with_multiple_new_fields(self): new_lib = DatabaseFixture4(self.libfile) @@ -214,7 +216,7 @@ def test_open_with_multiple_new_fields(self): c.execute("select * from test") row = c.fetchone() c.connection.close() - self.assertEqual(len(row.keys()), len(ModelFixture4._fields)) + assert len(row.keys()) == len(ModelFixture4._fields) def test_extra_model_adds_table(self): new_lib = DatabaseFixtureTwoModels(self.libfile) @@ -242,13 +244,13 @@ def test_mutate_increase_revision(self): "VALUES (?);".format(ModelFixture1._table), (111,), ) - self.assertGreater(self.db.revision, old_rev) + assert self.db.revision > old_rev def test_query_no_increase_revision(self): old_rev = self.db.revision with self.db.transaction() as tx: tx.query("PRAGMA table_info(%s)" % ModelFixture1._table) - self.assertEqual(self.db.revision, old_rev) + assert self.db.revision == old_rev class ModelTest(unittest.TestCase): @@ -262,7 +264,7 @@ def test_add_model(self): model = ModelFixture1() model.add(self.db) rows = self.db._connection().execute("select * from test").fetchall() - self.assertEqual(len(rows), 1) + assert len(rows) == 1 def test_store_fixed_field(self): model = ModelFixture1() @@ -270,37 +272,37 @@ def test_store_fixed_field(self): model.field_one = 123 model.store() row = self.db._connection().execute("select * from test").fetchone() - self.assertEqual(row["field_one"], 123) + assert row["field_one"] == 123 def test_revision(self): old_rev = self.db.revision model = ModelFixture1() model.add(self.db) model.store() - self.assertEqual(model._revision, self.db.revision) - self.assertGreater(self.db.revision, old_rev) + assert model._revision == self.db.revision + assert self.db.revision > old_rev mid_rev = self.db.revision model2 = ModelFixture1() model2.add(self.db) model2.store() - self.assertGreater(model2._revision, mid_rev) - self.assertGreater(self.db.revision, model._revision) + assert model2._revision > mid_rev + assert self.db.revision > model._revision # revision changed, so the model should be re-loaded model.load() - self.assertEqual(model._revision, self.db.revision) + assert model._revision == self.db.revision # revision did not change, so no reload mod2_old_rev = model2._revision model2.load() - self.assertEqual(model2._revision, mod2_old_rev) + assert model2._revision == mod2_old_rev def test_retrieve_by_id(self): model = ModelFixture1() model.add(self.db) other_model = self.db._get(ModelFixture1, model.id) - self.assertEqual(model.id, other_model.id) + assert model.id == other_model.id def test_store_and_retrieve_flexattr(self): model = ModelFixture1() @@ -309,21 +311,21 @@ def test_store_and_retrieve_flexattr(self): model.store() other_model = self.db._get(ModelFixture1, model.id) - self.assertEqual(other_model.foo, "bar") + assert other_model.foo == "bar" def test_delete_flexattr(self): model = ModelFixture1() model["foo"] = "bar" - self.assertIn("foo", model) + assert "foo" in model del model["foo"] - self.assertNotIn("foo", model) + assert "foo" not in model def test_delete_flexattr_via_dot(self): model = ModelFixture1() model["foo"] = "bar" - self.assertIn("foo", model) + assert "foo" in model del model.foo - self.assertNotIn("foo", model) + assert "foo" not in model def test_delete_flexattr_persists(self): model = ModelFixture1() @@ -336,11 +338,11 @@ def test_delete_flexattr_persists(self): model.store() model = self.db._get(ModelFixture1, model.id) - self.assertNotIn("foo", model) + assert "foo" not in model def test_delete_non_existent_attribute(self): model = ModelFixture1() - with self.assertRaises(KeyError): + with pytest.raises(KeyError): del model["foo"] def test_delete_fixed_attribute(self): @@ -350,26 +352,26 @@ def test_delete_fixed_attribute(self): model.some_boolean_field = True for field, type_ in model._fields.items(): - self.assertNotEqual(model[field], type_.null) + assert model[field] != type_.null for field, type_ in model._fields.items(): del model[field] - self.assertEqual(model[field], type_.null) + assert model[field] == type_.null def test_null_value_normalization_by_type(self): model = ModelFixture1() model.field_one = None - self.assertEqual(model.field_one, 0) + assert model.field_one == 0 def test_null_value_stays_none_for_untyped_field(self): model = ModelFixture1() model.foo = None - self.assertIsNone(model.foo) + assert model.foo is None def test_normalization_for_typed_flex_fields(self): model = ModelFixture1() model.some_float_field = None - self.assertEqual(model.some_float_field, 0.0) + assert model.some_float_field == 0.0 def test_load_deleted_flex_field(self): model1 = ModelFixture1() @@ -377,47 +379,47 @@ def test_load_deleted_flex_field(self): model1.add(self.db) model2 = self.db._get(ModelFixture1, model1.id) - self.assertIn("flex_field", model2) + assert "flex_field" in model2 del model1["flex_field"] model1.store() model2.load() - self.assertNotIn("flex_field", model2) + assert "flex_field" not in model2 def test_check_db_fails(self): - with self.assertRaisesRegex(ValueError, "no database"): + with pytest.raises(ValueError, match="no database"): dbcore.Model()._check_db() - with self.assertRaisesRegex(ValueError, "no id"): + with pytest.raises(ValueError, match="no id"): ModelFixture1(self.db)._check_db() dbcore.Model(self.db)._check_db(need_id=False) def test_missing_field(self): - with self.assertRaises(AttributeError): + with pytest.raises(AttributeError): ModelFixture1(self.db).nonExistingKey def test_computed_field(self): model = ModelFixtureWithGetters() - self.assertEqual(model.aComputedField, "thing") - with self.assertRaisesRegex(KeyError, "computed field .+ deleted"): + assert model.aComputedField == "thing" + with pytest.raises(KeyError, match="computed field .+ deleted"): del model.aComputedField def test_items(self): model = ModelFixture1(self.db) model.id = 5 - self.assertEqual( - {("id", 5), ("field_one", 0), ("field_two", "")}, set(model.items()) + assert {("id", 5), ("field_one", 0), ("field_two", "")} == set( + model.items() ) def test_delete_internal_field(self): model = dbcore.Model() del model._db - with self.assertRaises(AttributeError): + with pytest.raises(AttributeError): model._db def test_parse_nonstring(self): - with self.assertRaisesRegex(TypeError, "must be a string"): + with pytest.raises(TypeError, match="must be a string"): dbcore.Model._parse(None, 42) @@ -426,87 +428,87 @@ def test_format_fixed_field_integer(self): model = ModelFixture1() model.field_one = 155 value = model.formatted().get("field_one") - self.assertEqual(value, "155") + assert value == "155" def test_format_fixed_field_integer_normalized(self): """The normalize method of the Integer class rounds floats""" model = ModelFixture1() model.field_one = 142.432 value = model.formatted().get("field_one") - self.assertEqual(value, "142") + assert value == "142" model.field_one = 142.863 value = model.formatted().get("field_one") - self.assertEqual(value, "143") + assert value == "143" def test_format_fixed_field_string(self): model = ModelFixture1() model.field_two = "caf\xe9" value = model.formatted().get("field_two") - self.assertEqual(value, "caf\xe9") + assert value == "caf\xe9" def test_format_flex_field(self): model = ModelFixture1() model.other_field = "caf\xe9" value = model.formatted().get("other_field") - self.assertEqual(value, "caf\xe9") + assert value == "caf\xe9" def test_format_flex_field_bytes(self): model = ModelFixture1() model.other_field = "caf\xe9".encode() value = model.formatted().get("other_field") - self.assertTrue(isinstance(value, str)) - self.assertEqual(value, "caf\xe9") + assert isinstance(value, str) + assert value == "caf\xe9" def test_format_unset_field(self): model = ModelFixture1() value = model.formatted().get("other_field") - self.assertEqual(value, "") + assert value == "" def test_format_typed_flex_field(self): model = ModelFixture1() model.some_float_field = 3.14159265358979 value = model.formatted().get("some_float_field") - self.assertEqual(value, "3.1") + assert value == "3.1" class FormattedMappingTest(unittest.TestCase): def test_keys_equal_model_keys(self): model = ModelFixture1() formatted = model.formatted() - self.assertEqual(set(model.keys(True)), set(formatted.keys())) + assert set(model.keys(True)) == set(formatted.keys()) def test_get_unset_field(self): model = ModelFixture1() formatted = model.formatted() - with self.assertRaises(KeyError): + with pytest.raises(KeyError): formatted["other_field"] def test_get_method_with_default(self): model = ModelFixture1() formatted = model.formatted() - self.assertEqual(formatted.get("other_field"), "") + assert formatted.get("other_field") == "" def test_get_method_with_specified_default(self): model = ModelFixture1() formatted = model.formatted() - self.assertEqual(formatted.get("other_field", "default"), "default") + assert formatted.get("other_field", "default") == "default" class ParseTest(unittest.TestCase): def test_parse_fixed_field(self): value = ModelFixture1._parse("field_one", "2") - self.assertIsInstance(value, int) - self.assertEqual(value, 2) + assert isinstance(value, int) + assert value == 2 def test_parse_flex_field(self): value = ModelFixture1._parse("some_float_field", "2") - self.assertIsInstance(value, float) - self.assertEqual(value, 2.0) + assert isinstance(value, float) + assert value == 2.0 def test_parse_untyped_field(self): value = ModelFixture1._parse("field_nine", "2") - self.assertEqual(value, "2") + assert value == "2" class QueryParseTest(unittest.TestCase): @@ -522,52 +524,52 @@ def pqp(self, part): def test_one_basic_term(self): q = "test" r = (None, "test", dbcore.query.SubstringQuery) - self.assertEqual(self.pqp(q), r) + assert self.pqp(q) == r def test_one_keyed_term(self): q = "test:val" r = ("test", "val", dbcore.query.SubstringQuery) - self.assertEqual(self.pqp(q), r) + assert self.pqp(q) == r def test_colon_at_end(self): q = "test:" r = ("test", "", dbcore.query.SubstringQuery) - self.assertEqual(self.pqp(q), r) + assert self.pqp(q) == r def test_one_basic_regexp(self): q = r":regexp" r = (None, "regexp", dbcore.query.RegexpQuery) - self.assertEqual(self.pqp(q), r) + assert self.pqp(q) == r def test_keyed_regexp(self): q = r"test::regexp" r = ("test", "regexp", dbcore.query.RegexpQuery) - self.assertEqual(self.pqp(q), r) + assert self.pqp(q) == r def test_escaped_colon(self): q = r"test\:val" r = (None, "test:val", dbcore.query.SubstringQuery) - self.assertEqual(self.pqp(q), r) + assert self.pqp(q) == r def test_escaped_colon_in_regexp(self): q = r":test\:regexp" r = (None, "test:regexp", dbcore.query.RegexpQuery) - self.assertEqual(self.pqp(q), r) + assert self.pqp(q) == r def test_single_year(self): q = "year:1999" r = ("year", "1999", dbcore.query.NumericQuery) - self.assertEqual(self.pqp(q), r) + assert self.pqp(q) == r def test_multiple_years(self): q = "year:1999..2010" r = ("year", "1999..2010", dbcore.query.NumericQuery) - self.assertEqual(self.pqp(q), r) + assert self.pqp(q) == r def test_empty_query_part(self): q = "" r = (None, "", dbcore.query.SubstringQuery) - self.assertEqual(self.pqp(q), r) + assert self.pqp(q) == r class QueryFromStringsTest(unittest.TestCase): @@ -581,28 +583,28 @@ def qfs(self, strings): def test_zero_parts(self): q = self.qfs([]) - self.assertIsInstance(q, dbcore.query.AndQuery) - self.assertEqual(len(q.subqueries), 1) - self.assertIsInstance(q.subqueries[0], dbcore.query.TrueQuery) + assert isinstance(q, dbcore.query.AndQuery) + assert len(q.subqueries) == 1 + assert isinstance(q.subqueries[0], dbcore.query.TrueQuery) def test_two_parts(self): q = self.qfs(["foo", "bar:baz"]) - self.assertIsInstance(q, dbcore.query.AndQuery) - self.assertEqual(len(q.subqueries), 2) - self.assertIsInstance(q.subqueries[0], dbcore.query.AnyFieldQuery) - self.assertIsInstance(q.subqueries[1], dbcore.query.SubstringQuery) + assert isinstance(q, dbcore.query.AndQuery) + assert len(q.subqueries) == 2 + assert isinstance(q.subqueries[0], dbcore.query.AnyFieldQuery) + assert isinstance(q.subqueries[1], dbcore.query.SubstringQuery) def test_parse_fixed_type_query(self): q = self.qfs(["field_one:2..3"]) - self.assertIsInstance(q.subqueries[0], dbcore.query.NumericQuery) + assert isinstance(q.subqueries[0], dbcore.query.NumericQuery) def test_parse_flex_type_query(self): q = self.qfs(["some_float_field:2..3"]) - self.assertIsInstance(q.subqueries[0], dbcore.query.NumericQuery) + assert isinstance(q.subqueries[0], dbcore.query.NumericQuery) def test_empty_query_part(self): q = self.qfs([""]) - self.assertIsInstance(q.subqueries[0], dbcore.query.TrueQuery) + assert isinstance(q.subqueries[0], dbcore.query.TrueQuery) class SortFromStringsTest(unittest.TestCase): @@ -614,31 +616,31 @@ def sfs(self, strings): def test_zero_parts(self): s = self.sfs([]) - self.assertIsInstance(s, dbcore.query.NullSort) - self.assertEqual(s, dbcore.query.NullSort()) + assert isinstance(s, dbcore.query.NullSort) + assert s == dbcore.query.NullSort() def test_one_parts(self): s = self.sfs(["field+"]) - self.assertIsInstance(s, dbcore.query.Sort) + assert isinstance(s, dbcore.query.Sort) def test_two_parts(self): s = self.sfs(["field+", "another_field-"]) - self.assertIsInstance(s, dbcore.query.MultipleSort) - self.assertEqual(len(s.sorts), 2) + assert isinstance(s, dbcore.query.MultipleSort) + assert len(s.sorts) == 2 def test_fixed_field_sort(self): s = self.sfs(["field_one+"]) - self.assertIsInstance(s, dbcore.query.FixedFieldSort) - self.assertEqual(s, dbcore.query.FixedFieldSort("field_one")) + assert isinstance(s, dbcore.query.FixedFieldSort) + assert s == dbcore.query.FixedFieldSort("field_one") def test_flex_field_sort(self): s = self.sfs(["flex_field+"]) - self.assertIsInstance(s, dbcore.query.SlowFieldSort) - self.assertEqual(s, dbcore.query.SlowFieldSort("flex_field")) + assert isinstance(s, dbcore.query.SlowFieldSort) + assert s == dbcore.query.SlowFieldSort("flex_field") def test_special_sort(self): s = self.sfs(["some_sort+"]) - self.assertIsInstance(s, SortFixture) + assert isinstance(s, SortFixture) class ParseSortedQueryTest(unittest.TestCase): @@ -650,45 +652,45 @@ def psq(self, parts): def test_and_query(self): q, s = self.psq("foo bar") - self.assertIsInstance(q, dbcore.query.AndQuery) - self.assertIsInstance(s, dbcore.query.NullSort) - self.assertEqual(len(q.subqueries), 2) + assert isinstance(q, dbcore.query.AndQuery) + assert isinstance(s, dbcore.query.NullSort) + assert len(q.subqueries) == 2 def test_or_query(self): q, s = self.psq("foo , bar") - self.assertIsInstance(q, dbcore.query.OrQuery) - self.assertIsInstance(s, dbcore.query.NullSort) - self.assertEqual(len(q.subqueries), 2) + assert isinstance(q, dbcore.query.OrQuery) + assert isinstance(s, dbcore.query.NullSort) + assert len(q.subqueries) == 2 def test_no_space_before_comma_or_query(self): q, s = self.psq("foo, bar") - self.assertIsInstance(q, dbcore.query.OrQuery) - self.assertIsInstance(s, dbcore.query.NullSort) - self.assertEqual(len(q.subqueries), 2) + assert isinstance(q, dbcore.query.OrQuery) + assert isinstance(s, dbcore.query.NullSort) + assert len(q.subqueries) == 2 def test_no_spaces_or_query(self): q, s = self.psq("foo,bar") - self.assertIsInstance(q, dbcore.query.AndQuery) - self.assertIsInstance(s, dbcore.query.NullSort) - self.assertEqual(len(q.subqueries), 1) + assert isinstance(q, dbcore.query.AndQuery) + assert isinstance(s, dbcore.query.NullSort) + assert len(q.subqueries) == 1 def test_trailing_comma_or_query(self): q, s = self.psq("foo , bar ,") - self.assertIsInstance(q, dbcore.query.OrQuery) - self.assertIsInstance(s, dbcore.query.NullSort) - self.assertEqual(len(q.subqueries), 3) + assert isinstance(q, dbcore.query.OrQuery) + assert isinstance(s, dbcore.query.NullSort) + assert len(q.subqueries) == 3 def test_leading_comma_or_query(self): q, s = self.psq(", foo , bar") - self.assertIsInstance(q, dbcore.query.OrQuery) - self.assertIsInstance(s, dbcore.query.NullSort) - self.assertEqual(len(q.subqueries), 3) + assert isinstance(q, dbcore.query.OrQuery) + assert isinstance(s, dbcore.query.NullSort) + assert len(q.subqueries) == 3 def test_only_direction(self): q, s = self.psq("-") - self.assertIsInstance(q, dbcore.query.AndQuery) - self.assertIsInstance(s, dbcore.query.NullSort) - self.assertEqual(len(q.subqueries), 1) + assert isinstance(q, dbcore.query.AndQuery) + assert isinstance(s, dbcore.query.NullSort) + assert len(q.subqueries) == 1 class ResultsIteratorTest(unittest.TestCase): @@ -706,12 +708,12 @@ def tearDown(self): def test_iterate_once(self): objs = self.db._fetch(ModelFixture1) - self.assertEqual(len(list(objs)), 2) + assert len(list(objs)) == 2 def test_iterate_twice(self): objs = self.db._fetch(ModelFixture1) list(objs) - self.assertEqual(len(list(objs)), 2) + assert len(list(objs)) == 2 def test_concurrent_iterators(self): results = self.db._fetch(ModelFixture1) @@ -719,46 +721,47 @@ def test_concurrent_iterators(self): it2 = iter(results) next(it1) list(it2) - self.assertEqual(len(list(it1)), 1) + assert len(list(it1)) == 1 def test_slow_query(self): q = dbcore.query.SubstringQuery("foo", "ba", False) objs = self.db._fetch(ModelFixture1, q) - self.assertEqual(len(list(objs)), 2) + assert len(list(objs)) == 2 def test_slow_query_negative(self): q = dbcore.query.SubstringQuery("foo", "qux", False) objs = self.db._fetch(ModelFixture1, q) - self.assertEqual(len(list(objs)), 0) + assert len(list(objs)) == 0 def test_iterate_slow_sort(self): s = dbcore.query.SlowFieldSort("foo") res = self.db._fetch(ModelFixture1, sort=s) objs = list(res) - self.assertEqual(objs[0].foo, "bar") - self.assertEqual(objs[1].foo, "baz") + assert objs[0].foo == "bar" + assert objs[1].foo == "baz" def test_unsorted_subscript(self): objs = self.db._fetch(ModelFixture1) - self.assertEqual(objs[0].foo, "baz") - self.assertEqual(objs[1].foo, "bar") + assert objs[0].foo == "baz" + assert objs[1].foo == "bar" def test_slow_sort_subscript(self): s = dbcore.query.SlowFieldSort("foo") objs = self.db._fetch(ModelFixture1, sort=s) - self.assertEqual(objs[0].foo, "bar") - self.assertEqual(objs[1].foo, "baz") + assert objs[0].foo == "bar" + assert objs[1].foo == "baz" def test_length(self): objs = self.db._fetch(ModelFixture1) - self.assertEqual(len(objs), 2) + assert len(objs) == 2 def test_out_of_range(self): objs = self.db._fetch(ModelFixture1) - with self.assertRaises(IndexError): + with pytest.raises(IndexError): objs[100] def test_no_results(self): - self.assertIsNone( + assert ( self.db._fetch(ModelFixture1, dbcore.query.FalseQuery()).get() + is None ) diff --git a/test/test_files.py b/test/test_files.py index 99e790fe4b..e189fe73ce 100644 --- a/test/test_files.py +++ b/test/test_files.py @@ -21,6 +21,8 @@ import unittest from os.path import join +import pytest + import beets.library from beets import util from beets.test import _common @@ -107,37 +109,37 @@ def test_force_reflink_does_not_depart(self): def test_move_changes_path(self): self.i.move() - self.assertEqual(self.i.path, util.normpath(self.dest)) + assert self.i.path == util.normpath(self.dest) def test_copy_already_at_destination(self): self.i.move() old_path = self.i.path self.i.move(operation=MoveOperation.COPY) - self.assertEqual(self.i.path, old_path) + assert self.i.path == old_path def test_move_already_at_destination(self): self.i.move() old_path = self.i.path self.i.move() - self.assertEqual(self.i.path, old_path) + assert self.i.path == old_path def test_move_file_with_colon(self): self.i.artist = "C:DOS" self.i.move() - self.assertIn("C_DOS", self.i.path.decode()) + assert "C_DOS" in self.i.path.decode() def test_move_file_with_multiple_colons(self): # print(beets.config["replace"]) self.i.artist = "COM:DOS" self.i.move() - self.assertIn("COM_DOS", self.i.path.decode()) + assert "COM_DOS" in self.i.path.decode() def test_move_file_with_colon_alt_separator(self): old = beets.config["drive_sep_replace"] beets.config["drive_sep_replace"] = "0" self.i.artist = "C:DOS" self.i.move() - self.assertIn("C0DOS", self.i.path.decode()) + assert "C0DOS" in self.i.path.decode() beets.config["drive_sep_replace"] = old def test_read_only_file_copied_writable(self): @@ -146,7 +148,7 @@ def test_read_only_file_copied_writable(self): try: self.i.move(operation=MoveOperation.COPY) - self.assertTrue(os.access(syspath(self.i.path), os.W_OK)) + assert os.access(syspath(self.i.path), os.W_OK) finally: # Make everything writable so it can be cleaned up. os.chmod(syspath(self.path), 0o777) @@ -159,18 +161,15 @@ def test_move_avoids_collision_with_existing_file(self): touch(dest) self.i.move() - self.assertNotEqual(self.i.path, dest) - self.assertEqual(os.path.dirname(self.i.path), os.path.dirname(dest)) + assert self.i.path != dest + assert os.path.dirname(self.i.path) == os.path.dirname(dest) @unittest.skipUnless(_common.HAVE_SYMLINK, "need symlinks") def test_link_arrives(self): self.i.move(operation=MoveOperation.LINK) self.assertExists(self.dest) - self.assertTrue(os.path.islink(syspath(self.dest))) - self.assertEqual( - bytestring_path(os.readlink(syspath(self.dest))), - self.path, - ) + assert os.path.islink(syspath(self.dest)) + assert bytestring_path(os.readlink(syspath(self.dest))) == self.path @unittest.skipUnless(_common.HAVE_SYMLINK, "need symlinks") def test_link_does_not_depart(self): @@ -180,7 +179,7 @@ def test_link_does_not_depart(self): @unittest.skipUnless(_common.HAVE_SYMLINK, "need symlinks") def test_link_changes_path(self): self.i.move(operation=MoveOperation.LINK) - self.assertEqual(self.i.path, util.normpath(self.dest)) + assert self.i.path == util.normpath(self.dest) @unittest.skipUnless(_common.HAVE_HARDLINK, "need hardlinks") def test_hardlink_arrives(self): @@ -188,9 +187,9 @@ def test_hardlink_arrives(self): self.assertExists(self.dest) s1 = os.stat(syspath(self.path)) s2 = os.stat(syspath(self.dest)) - self.assertTrue( - (s1[stat.ST_INO], s1[stat.ST_DEV]) - == (s2[stat.ST_INO], s2[stat.ST_DEV]) + assert (s1[stat.ST_INO], s1[stat.ST_DEV]) == ( + s2[stat.ST_INO], + s2[stat.ST_DEV], ) @unittest.skipUnless(_common.HAVE_HARDLINK, "need hardlinks") @@ -201,44 +200,44 @@ def test_hardlink_does_not_depart(self): @unittest.skipUnless(_common.HAVE_HARDLINK, "need hardlinks") def test_hardlink_changes_path(self): self.i.move(operation=MoveOperation.HARDLINK) - self.assertEqual(self.i.path, util.normpath(self.dest)) + assert self.i.path == util.normpath(self.dest) class HelperTest(BeetsTestCase): def test_ancestry_works_on_file(self): p = "/a/b/c" a = ["/", "/a", "/a/b"] - self.assertEqual(util.ancestry(p), a) + assert util.ancestry(p) == a def test_ancestry_works_on_dir(self): p = "/a/b/c/" a = ["/", "/a", "/a/b", "/a/b/c"] - self.assertEqual(util.ancestry(p), a) + assert util.ancestry(p) == a def test_ancestry_works_on_relative(self): p = "a/b/c" a = ["a", "a/b"] - self.assertEqual(util.ancestry(p), a) + assert util.ancestry(p) == a def test_components_works_on_file(self): p = "/a/b/c" a = ["/", "a", "b", "c"] - self.assertEqual(util.components(p), a) + assert util.components(p) == a def test_components_works_on_dir(self): p = "/a/b/c/" a = ["/", "a", "b", "c"] - self.assertEqual(util.components(p), a) + assert util.components(p) == a def test_components_works_on_relative(self): p = "a/b/c" a = ["a", "b", "c"] - self.assertEqual(util.components(p), a) + assert util.components(p) == a def test_forward_slash(self): p = rb"C:\a\b\c" a = rb"C:/a/b/c" - self.assertEqual(util.path_as_posix(p), a) + assert util.path_as_posix(p) == a class AlbumFileTest(BeetsTestCase): @@ -265,7 +264,7 @@ def test_albuminfo_move_changes_paths(self): self.ai.store() self.i.load() - self.assertTrue(b"newAlbumName" in self.i.path) + assert b"newAlbumName" in self.i.path def test_albuminfo_move_moves_file(self): oldpath = self.i.path @@ -295,14 +294,14 @@ def test_albuminfo_move_reflinks_file(self): self.ai.store() self.i.load() - self.assertTrue(os.path.exists(oldpath)) - self.assertTrue(os.path.exists(self.i.path)) + assert os.path.exists(oldpath) + assert os.path.exists(self.i.path) def test_albuminfo_move_to_custom_dir(self): self.ai.move(basedir=self.otherdir) self.i.load() self.ai.store() - self.assertIn(b"testotherdir", self.i.path) + assert b"testotherdir" in self.i.path class ArtFileTest(BeetsTestCase): @@ -337,7 +336,7 @@ def test_art_moves_with_album(self): self.ai.move() self.i.load() - self.assertNotEqual(self.i.path, oldpath) + assert self.i.path != oldpath self.assertNotExists(self.art) newart = self.lib.get_album(self.i).art_destination(self.art) self.assertExists(newart) @@ -352,7 +351,7 @@ def test_art_moves_with_album_to_custom_dir(self): self.assertNotExists(self.art) newart = self.lib.get_album(self.i).artpath self.assertExists(newart) - self.assertIn(b"testotherdir", newart) + assert b"testotherdir" in newart def test_setart_copies_image(self): util.remove(self.art) @@ -365,7 +364,7 @@ def test_setart_copies_image(self): ai = self.lib.add_album((i2,)) i2.move(operation=MoveOperation.COPY) - self.assertIsNone(ai.artpath) + assert ai.artpath is None ai.set_art(newart) self.assertExists(ai.artpath) @@ -418,8 +417,8 @@ def test_setart_to_conflicting_file_gets_new_path(self): # Set the art. ai.set_art(newart) - self.assertNotEqual(artdest, ai.artpath) - self.assertEqual(os.path.dirname(artdest), os.path.dirname(ai.artpath)) + assert artdest != ai.artpath + assert os.path.dirname(artdest) == os.path.dirname(ai.artpath) def test_setart_sets_permissions(self): util.remove(self.art) @@ -437,8 +436,8 @@ def test_setart_sets_permissions(self): ai.set_art(newart) mode = stat.S_IMODE(os.stat(syspath(ai.artpath)).st_mode) - self.assertTrue(mode & stat.S_IRGRP) - self.assertTrue(os.access(syspath(ai.artpath), os.W_OK)) + assert mode & stat.S_IRGRP + assert os.access(syspath(ai.artpath), os.W_OK) finally: # Make everything writable so it can be cleaned up. @@ -454,7 +453,7 @@ def test_move_last_file_moves_albumart(self): self.ai.items()[0].move() artpath = self.lib.albums()[0].artpath - self.assertTrue(b"different_album" in artpath) + assert b"different_album" in artpath self.assertExists(artpath) self.assertNotExists(oldartpath) @@ -471,8 +470,8 @@ def test_move_not_last_file_does_not_move_albumart(self): self.i.move() artpath = self.lib.albums()[0].artpath - self.assertNotIn(b"different_album", artpath) - self.assertEqual(artpath, oldartpath) + assert b"different_album" not in artpath + assert artpath == oldartpath self.assertExists(oldartpath) @@ -579,16 +578,16 @@ def test_successful_reflink(self): self.assertExists(self.path) def test_unsuccessful_move(self): - with self.assertRaises(util.FilesystemError): + with pytest.raises(util.FilesystemError): util.move(self.path, self.otherpath) def test_unsuccessful_copy(self): - with self.assertRaises(util.FilesystemError): + with pytest.raises(util.FilesystemError): util.copy(self.path, self.otherpath) @unittest.skipUnless(_common.HAVE_REFLINK, "need reflink") def test_unsuccessful_reflink(self): - with self.assertRaises(util.FilesystemError): + with pytest.raises(util.FilesystemError): util.reflink(self.path, self.otherpath) def test_self_move(self): @@ -633,25 +632,25 @@ def setUp(self): def test_sorted_files(self): res = list(util.sorted_walk(self.base)) - self.assertEqual(len(res), 2) - self.assertEqual(res[0], (self.base, [b"d"], [b"x", b"y"])) - self.assertEqual(res[1], (os.path.join(self.base, b"d"), [], [b"z"])) + assert len(res) == 2 + assert res[0] == (self.base, [b"d"], [b"x", b"y"]) + assert res[1] == (os.path.join(self.base, b"d"), [], [b"z"]) def test_ignore_file(self): res = list(util.sorted_walk(self.base, (b"x",))) - self.assertEqual(len(res), 2) - self.assertEqual(res[0], (self.base, [b"d"], [b"y"])) - self.assertEqual(res[1], (os.path.join(self.base, b"d"), [], [b"z"])) + assert len(res) == 2 + assert res[0] == (self.base, [b"d"], [b"y"]) + assert res[1] == (os.path.join(self.base, b"d"), [], [b"z"]) def test_ignore_directory(self): res = list(util.sorted_walk(self.base, (b"d",))) - self.assertEqual(len(res), 1) - self.assertEqual(res[0], (self.base, [], [b"x", b"y"])) + assert len(res) == 1 + assert res[0] == (self.base, [], [b"x", b"y"]) def test_ignore_everything(self): res = list(util.sorted_walk(self.base, (b"*",))) - self.assertEqual(len(res), 1) - self.assertEqual(res[0], (self.base, [], [])) + assert len(res) == 1 + assert res[0] == (self.base, [], []) class UniquePathTest(BeetsTestCase): @@ -667,19 +666,19 @@ def setUp(self): def test_new_file_unchanged(self): path = util.unique_path(os.path.join(self.base, b"z.mp3")) - self.assertEqual(path, os.path.join(self.base, b"z.mp3")) + assert path == os.path.join(self.base, b"z.mp3") def test_conflicting_file_appends_1(self): path = util.unique_path(os.path.join(self.base, b"y.mp3")) - self.assertEqual(path, os.path.join(self.base, b"y.1.mp3")) + assert path == os.path.join(self.base, b"y.1.mp3") def test_conflicting_file_appends_higher_number(self): path = util.unique_path(os.path.join(self.base, b"x.mp3")) - self.assertEqual(path, os.path.join(self.base, b"x.3.mp3")) + assert path == os.path.join(self.base, b"x.3.mp3") def test_conflicting_file_with_number_increases_number(self): path = util.unique_path(os.path.join(self.base, b"x.1.mp3")) - self.assertEqual(path, os.path.join(self.base, b"x.3.mp3")) + assert path == os.path.join(self.base, b"x.3.mp3") class MkDirAllTest(BeetsTestCase): diff --git a/test/test_hidden.py b/test/test_hidden.py index 290bbe74b3..e7af321336 100644 --- a/test/test_hidden.py +++ b/test/test_hidden.py @@ -45,7 +45,7 @@ def test_osx_hidden(self): else: raise e - self.assertTrue(hidden.is_hidden(f.name)) + assert hidden.is_hidden(f.name) def test_windows_hidden(self): if not sys.platform == "win32": @@ -64,7 +64,7 @@ def test_windows_hidden(self): if not success: self.skipTest("unable to set file attributes") - self.assertTrue(hidden.is_hidden(f.name)) + assert hidden.is_hidden(f.name) def test_other_hidden(self): if sys.platform == "darwin" or sys.platform == "win32": @@ -73,4 +73,4 @@ def test_other_hidden(self): with tempfile.NamedTemporaryFile(prefix=".tmp") as f: fn = util.bytestring_path(f.name) - self.assertTrue(hidden.is_hidden(fn)) + assert hidden.is_hidden(fn) diff --git a/test/test_importer.py b/test/test_importer.py index 80f3954224..0ac2a984a4 100644 --- a/test/test_importer.py +++ b/test/test_importer.py @@ -29,6 +29,7 @@ from unittest.mock import Mock, patch from zipfile import ZipFile +import pytest from mediafile import MediaFile from beets import config, importer, logging, util @@ -56,42 +57,42 @@ def test_tags_not_scrubbed(self): config["scrub"]["auto"] = False config["import"]["write"] = True for mediafile in self.import_media: - self.assertEqual(mediafile.artist, "Tag Artist") - self.assertEqual(mediafile.album, "Tag Album") + assert mediafile.artist == "Tag Artist" + assert mediafile.album == "Tag Album" self.run_asis_importer() for item in self.lib.items(): imported_file = os.path.join(item.path) imported_file = MediaFile(imported_file) - self.assertEqual(imported_file.artist, "Tag Artist") - self.assertEqual(imported_file.album, "Tag Album") + assert imported_file.artist == "Tag Artist" + assert imported_file.album == "Tag Album" def test_tags_restored(self): config["plugins"] = ["scrub"] config["scrub"]["auto"] = True config["import"]["write"] = True for mediafile in self.import_media: - self.assertEqual(mediafile.artist, "Tag Artist") - self.assertEqual(mediafile.album, "Tag Album") + assert mediafile.artist == "Tag Artist" + assert mediafile.album == "Tag Album" self.run_asis_importer() for item in self.lib.items(): imported_file = os.path.join(item.path) imported_file = MediaFile(imported_file) - self.assertEqual(imported_file.artist, "Tag Artist") - self.assertEqual(imported_file.album, "Tag Album") + assert imported_file.artist == "Tag Artist" + assert imported_file.album == "Tag Album" def test_tags_not_restored(self): config["plugins"] = ["scrub"] config["scrub"]["auto"] = True config["import"]["write"] = False for mediafile in self.import_media: - self.assertEqual(mediafile.artist, "Tag Artist") - self.assertEqual(mediafile.album, "Tag Album") + assert mediafile.artist == "Tag Artist" + assert mediafile.album == "Tag Album" self.run_asis_importer() for item in self.lib.items(): imported_file = os.path.join(item.path) imported_file = MediaFile(imported_file) - self.assertIsNone(imported_file.artist) - self.assertIsNone(imported_file.album) + assert imported_file.artist is None + assert imported_file.album is None @_common.slow_test() @@ -101,8 +102,8 @@ class NonAutotaggedImportTest(AsIsImporterMixin, ImportTestCase): def test_album_created_with_track_artist(self): self.run_asis_importer() albums = self.lib.albums() - self.assertEqual(len(albums), 1) - self.assertEqual(albums[0].albumartist, "Tag Artist") + assert len(albums) == 1 + assert albums[0].albumartist == "Tag Artist" def test_import_copy_arrives(self): self.run_asis_importer() @@ -184,7 +185,7 @@ def test_import_link_arrives(self): util.bytestring_path(f"{mediafile.title}.mp3"), ) self.assertExists(filename) - self.assertTrue(os.path.islink(syspath(filename))) + assert os.path.islink(syspath(filename)) self.assert_equal_path( util.bytestring_path(os.readlink(syspath(filename))), mediafile.path, @@ -203,9 +204,9 @@ def test_import_hardlink_arrives(self): self.assertExists(filename) s1 = os.stat(syspath(mediafile.path)) s2 = os.stat(syspath(filename)) - self.assertTrue( - (s1[stat.ST_INO], s1[stat.ST_DEV]) - == (s2[stat.ST_INO], s2[stat.ST_DEV]) + assert (s1[stat.ST_INO], s1[stat.ST_DEV]) == ( + s2[stat.ST_INO], + s2[stat.ST_DEV], ) @unittest.skipUnless(_common.HAVE_REFLINK, "need reflinks") @@ -266,12 +267,12 @@ def test_rm(self): 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) + assert len(self.lib.items()) == 0 + assert len(self.lib.albums()) == 0 self.run_asis_importer(import_dir=zip_path) - self.assertEqual(len(self.lib.items()), 1) - self.assertEqual(len(self.lib.albums()), 1) + assert len(self.lib.items()) == 1 + assert len(self.lib.albums()) == 1 class ImportTarTest(ImportZipTest): @@ -320,18 +321,18 @@ def tearDown(self): self.matcher.restore() def test_apply_asis_adds_track(self): - self.assertIsNone(self.lib.items().get()) + assert self.lib.items().get() is None self.importer.add_choice(importer.action.ASIS) self.importer.run() - self.assertEqual(self.lib.items().get().title, "Tag Track 1") + assert self.lib.items().get().title == "Tag Track 1" def test_apply_asis_does_not_add_album(self): - self.assertIsNone(self.lib.albums().get()) + assert self.lib.albums().get() is None self.importer.add_choice(importer.action.ASIS) self.importer.run() - self.assertIsNone(self.lib.albums().get()) + assert self.lib.albums().get() is None def test_apply_asis_adds_singleton_path(self): self.assert_lib_dir_empty() @@ -341,16 +342,16 @@ def test_apply_asis_adds_singleton_path(self): self.assert_file_in_lib(b"singletons", b"Tag Track 1.mp3") def test_apply_candidate_adds_track(self): - self.assertIsNone(self.lib.items().get()) + assert self.lib.items().get() is None self.importer.add_choice(importer.action.APPLY) self.importer.run() - self.assertEqual(self.lib.items().get().title, "Applied Track 1") + assert self.lib.items().get().title == "Applied Track 1" def test_apply_candidate_does_not_add_album(self): self.importer.add_choice(importer.action.APPLY) self.importer.run() - self.assertIsNone(self.lib.albums().get()) + assert self.lib.albums().get() is None def test_apply_candidate_adds_singleton_path(self): self.assert_lib_dir_empty() @@ -362,14 +363,14 @@ def test_apply_candidate_adds_singleton_path(self): def test_skip_does_not_add_first_track(self): self.importer.add_choice(importer.action.SKIP) self.importer.run() - self.assertIsNone(self.lib.items().get()) + assert self.lib.items().get() is None def test_skip_adds_other_tracks(self): self.prepare_album_for_import(2) self.importer.add_choice(importer.action.SKIP) self.importer.add_choice(importer.action.ASIS) self.importer.run() - self.assertEqual(len(self.lib.items()), 1) + assert len(self.lib.items()) == 1 def test_import_single_files(self): resource_path = os.path.join(_common.RSRC, b"empty.mp3") @@ -387,8 +388,8 @@ def test_import_single_files(self): self.importer.add_choice(importer.action.ASIS) self.importer.run() - self.assertEqual(len(self.lib.items()), 2) - self.assertEqual(len(self.lib.albums()), 2) + assert len(self.lib.items()) == 2 + assert len(self.lib.albums()) == 2 def test_set_fields(self): genre = "\U0001F3B7 Jazz" @@ -401,29 +402,29 @@ def test_set_fields(self): } # As-is item import. - self.assertIsNone(self.lib.albums().get()) + assert self.lib.albums().get() is None self.importer.add_choice(importer.action.ASIS) self.importer.run() for item in self.lib.items(): item.load() # TODO: Not sure this is necessary. - self.assertEqual(item.genre, genre) - self.assertEqual(item.collection, collection) - self.assertEqual(item.title, "Tag Track 1 - formatted") + assert item.genre == genre + assert item.collection == collection + assert item.title == "Tag Track 1 - formatted" # Remove item from library to test again with APPLY choice. item.remove() # Autotagged. - self.assertIsNone(self.lib.albums().get()) + assert self.lib.albums().get() is None self.importer.clear_choices() self.importer.add_choice(importer.action.APPLY) self.importer.run() for item in self.lib.items(): item.load() - self.assertEqual(item.genre, genre) - self.assertEqual(item.collection, collection) - self.assertEqual(item.title, "Applied Track 1 - formatted") + assert item.genre == genre + assert item.collection == collection + assert item.title == "Applied Track 1 - formatted" class ImportTest(ImportTestCase): @@ -441,17 +442,17 @@ def tearDown(self): self.matcher.restore() def test_apply_asis_adds_album(self): - self.assertIsNone(self.lib.albums().get()) + assert self.lib.albums().get() is None self.importer.add_choice(importer.action.ASIS) self.importer.run() - self.assertEqual(self.lib.albums().get().album, "Tag Album") + assert self.lib.albums().get().album == "Tag Album" def test_apply_asis_adds_tracks(self): - self.assertIsNone(self.lib.items().get()) + assert self.lib.items().get() is None self.importer.add_choice(importer.action.ASIS) self.importer.run() - self.assertEqual(self.lib.items().get().title, "Tag Track 1") + assert self.lib.items().get().title == "Tag Track 1" def test_apply_asis_adds_album_path(self): self.assert_lib_dir_empty() @@ -461,18 +462,18 @@ def test_apply_asis_adds_album_path(self): self.assert_file_in_lib(b"Tag Artist", b"Tag Album", b"Tag Track 1.mp3") def test_apply_candidate_adds_album(self): - self.assertIsNone(self.lib.albums().get()) + assert self.lib.albums().get() is None self.importer.add_choice(importer.action.APPLY) self.importer.run() - self.assertEqual(self.lib.albums().get().album, "Applied Album") + assert self.lib.albums().get().album == "Applied Album" def test_apply_candidate_adds_tracks(self): - self.assertIsNone(self.lib.items().get()) + assert self.lib.items().get() is None self.importer.add_choice(importer.action.APPLY) self.importer.run() - self.assertEqual(self.lib.items().get().title, "Applied Track 1") + assert self.lib.items().get().title == "Applied Track 1" def test_apply_candidate_adds_album_path(self): self.assert_lib_dir_empty() @@ -492,14 +493,14 @@ def test_apply_from_scratch_removes_other_metadata(self): self.importer.add_choice(importer.action.APPLY) self.importer.run() - self.assertEqual(self.lib.items().get().genre, "") + assert self.lib.items().get().genre == "" def test_apply_from_scratch_keeps_format(self): config["import"]["from_scratch"] = True self.importer.add_choice(importer.action.APPLY) self.importer.run() - self.assertEqual(self.lib.items().get().format, "MP3") + assert self.lib.items().get().format == "MP3" def test_apply_from_scratch_keeps_bitrate(self): config["import"]["from_scratch"] = True @@ -507,7 +508,7 @@ def test_apply_from_scratch_keeps_bitrate(self): self.importer.add_choice(importer.action.APPLY) self.importer.run() - self.assertEqual(self.lib.items().get().bitrate, bitrate) + assert self.lib.items().get().bitrate == bitrate def test_apply_with_move_deletes_import(self): config["import"]["move"] = True @@ -532,21 +533,21 @@ def test_apply_with_delete_deletes_import(self): def test_skip_does_not_add_track(self): self.importer.add_choice(importer.action.SKIP) self.importer.run() - self.assertIsNone(self.lib.items().get()) + assert self.lib.items().get() is None def test_skip_non_album_dirs(self): self.assertIsDir(os.path.join(self.import_dir, b"album")) self.touch(b"cruft", dir=self.import_dir) self.importer.add_choice(importer.action.APPLY) self.importer.run() - self.assertEqual(len(self.lib.albums()), 1) + assert len(self.lib.albums()) == 1 def test_unmatched_tracks_not_added(self): self.prepare_album_for_import(2) self.matcher.matching = self.matcher.MISSING self.importer.add_choice(importer.action.APPLY) self.importer.run() - self.assertEqual(len(self.lib.items()), 1) + assert len(self.lib.items()) == 1 def test_empty_directory_warning(self): import_dir = os.path.join(self.temp_dir, b"empty") @@ -556,7 +557,7 @@ def test_empty_directory_warning(self): self.importer.run() import_dir = displayable_path(import_dir) - self.assertIn(f"No files imported from {import_dir}", logs) + assert f"No files imported from {import_dir}" in logs def test_empty_directory_singleton_warning(self): import_dir = os.path.join(self.temp_dir, b"empty") @@ -566,15 +567,15 @@ def test_empty_directory_singleton_warning(self): self.importer.run() import_dir = displayable_path(import_dir) - self.assertIn(f"No files imported from {import_dir}", logs) + assert f"No files imported from {import_dir}" in logs def test_asis_no_data_source(self): - self.assertIsNone(self.lib.items().get()) + assert self.lib.items().get() is None self.importer.add_choice(importer.action.ASIS) self.importer.run() - with self.assertRaises(AttributeError): + with pytest.raises(AttributeError): self.lib.items().get().data_source def test_set_fields(self): @@ -590,49 +591,42 @@ def test_set_fields(self): } # As-is album import. - self.assertIsNone(self.lib.albums().get()) + assert self.lib.albums().get() is None self.importer.add_choice(importer.action.ASIS) self.importer.run() for album in self.lib.albums(): album.load() # TODO: Not sure this is necessary. - self.assertEqual(album.genre, genre) - self.assertEqual(album.comments, comments) + assert album.genre == genre + assert album.comments == comments for item in album.items(): - self.assertEqual(item.get("genre", with_album=False), genre) - self.assertEqual( - item.get("collection", with_album=False), collection - ) - self.assertEqual( - item.get("comments", with_album=False), comments - ) - self.assertEqual( - item.get("album", with_album=False), "Tag Album - formatted" + assert item.get("genre", with_album=False) == genre + assert item.get("collection", with_album=False) == collection + assert item.get("comments", with_album=False) == comments + assert ( + item.get("album", with_album=False) + == "Tag Album - formatted" ) # Remove album from library to test again with APPLY choice. album.remove() # Autotagged. - self.assertIsNone(self.lib.albums().get()) + assert self.lib.albums().get() is None self.importer.clear_choices() self.importer.add_choice(importer.action.APPLY) self.importer.run() for album in self.lib.albums(): album.load() - self.assertEqual(album.genre, genre) - self.assertEqual(album.comments, comments) + assert album.genre == genre + assert album.comments == comments for item in album.items(): - self.assertEqual(item.get("genre", with_album=False), genre) - self.assertEqual( - item.get("collection", with_album=False), collection - ) - self.assertEqual( - item.get("comments", with_album=False), comments - ) - self.assertEqual( - item.get("album", with_album=False), - "Applied Album - formatted", + assert item.get("genre", with_album=False) == genre + assert item.get("collection", with_album=False) == collection + assert item.get("comments", with_album=False) == comments + assert ( + item.get("album", with_album=False) + == "Applied Album - formatted" ) @@ -650,15 +644,15 @@ def tearDown(self): self.matcher.restore() def test_apply_tracks_adds_singleton_track(self): - self.assertIsNone(self.lib.items().get()) - self.assertIsNone(self.lib.albums().get()) + assert self.lib.items().get() is None + assert self.lib.albums().get() is None self.importer.add_choice(importer.action.TRACKS) self.importer.add_choice(importer.action.APPLY) self.importer.add_choice(importer.action.APPLY) self.importer.run() - self.assertEqual(self.lib.items().get().title, "Applied Track 1") - self.assertIsNone(self.lib.albums().get()) + assert self.lib.items().get().title == "Applied Track 1" + assert self.lib.albums().get() is None def test_apply_tracks_adds_singleton_path(self): self.assert_lib_dir_empty() @@ -686,9 +680,9 @@ def tearDown(self): def test_asis_homogenous_sets_albumartist(self): self.importer.add_choice(importer.action.ASIS) self.importer.run() - self.assertEqual(self.lib.albums().get().albumartist, "Tag Artist") + assert self.lib.albums().get().albumartist == "Tag Artist" for item in self.lib.items(): - self.assertEqual(item.albumartist, "Tag Artist") + assert item.albumartist == "Tag Artist" def test_asis_heterogenous_sets_various_albumartist(self): self.import_media[0].artist = "Other Artist" @@ -698,9 +692,9 @@ def test_asis_heterogenous_sets_various_albumartist(self): self.importer.add_choice(importer.action.ASIS) self.importer.run() - self.assertEqual(self.lib.albums().get().albumartist, "Various Artists") + assert self.lib.albums().get().albumartist == "Various Artists" for item in self.lib.items(): - self.assertEqual(item.albumartist, "Various Artists") + assert item.albumartist == "Various Artists" def test_asis_heterogenous_sets_compilation(self): self.import_media[0].artist = "Other Artist" @@ -711,7 +705,7 @@ def test_asis_heterogenous_sets_compilation(self): self.importer.add_choice(importer.action.ASIS) self.importer.run() for item in self.lib.items(): - self.assertTrue(item.comp) + assert item.comp def test_asis_sets_majority_albumartist(self): self.import_media[0].artist = "Other Artist" @@ -721,9 +715,9 @@ def test_asis_sets_majority_albumartist(self): self.importer.add_choice(importer.action.ASIS) self.importer.run() - self.assertEqual(self.lib.albums().get().albumartist, "Other Artist") + assert self.lib.albums().get().albumartist == "Other Artist" for item in self.lib.items(): - self.assertEqual(item.albumartist, "Other Artist") + assert item.albumartist == "Other Artist" def test_asis_albumartist_tag_sets_albumartist(self): self.import_media[0].artist = "Other Artist" @@ -735,13 +729,11 @@ def test_asis_albumartist_tag_sets_albumartist(self): self.importer.add_choice(importer.action.ASIS) self.importer.run() - self.assertEqual(self.lib.albums().get().albumartist, "Album Artist") - self.assertEqual( - self.lib.albums().get().mb_albumartistid, "Album Artist ID" - ) + assert self.lib.albums().get().albumartist == "Album Artist" + assert self.lib.albums().get().mb_albumartistid == "Album Artist ID" for item in self.lib.items(): - self.assertEqual(item.albumartist, "Album Artist") - self.assertEqual(item.mb_albumartistid, "Album Artist ID") + assert item.albumartist == "Album Artist" + assert item.mb_albumartistid == "Album Artist ID" def test_asis_albumartists_tag_sets_multi_albumartists(self): self.import_media[0].artist = "Other Artist" @@ -756,37 +748,29 @@ def test_asis_albumartists_tag_sets_multi_albumartists(self): self.importer.add_choice(importer.action.ASIS) self.importer.run() - self.assertEqual(self.lib.albums().get().albumartist, "Album Artist") - self.assertEqual( - self.lib.albums().get().albumartists, - ["Album Artist 1", "Album Artist 2"], - ) - self.assertEqual( - self.lib.albums().get().mb_albumartistid, "Album Artist ID" - ) + assert self.lib.albums().get().albumartist == "Album Artist" + assert self.lib.albums().get().albumartists == [ + "Album Artist 1", + "Album Artist 2", + ] + assert self.lib.albums().get().mb_albumartistid == "Album Artist ID" # Make sure both custom media items get tested asserted_multi_artists_0 = False asserted_multi_artists_1 = False for item in self.lib.items(): - self.assertEqual(item.albumartist, "Album Artist") - self.assertEqual( - item.albumartists, ["Album Artist 1", "Album Artist 2"] - ) - self.assertEqual(item.mb_albumartistid, "Album Artist ID") + assert item.albumartist == "Album Artist" + assert item.albumartists == ["Album Artist 1", "Album Artist 2"] + assert item.mb_albumartistid == "Album Artist ID" if item.artist == "Other Artist": asserted_multi_artists_0 = True - self.assertEqual( - item.artists, ["Other Artist", "Other Artist 2"] - ) + assert item.artists == ["Other Artist", "Other Artist 2"] if item.artist == "Another Artist": asserted_multi_artists_1 = True - self.assertEqual( - item.artists, ["Another Artist", "Another Artist 2"] - ) + assert item.artists == ["Another Artist", "Another Artist 2"] - self.assertTrue(asserted_multi_artists_0 and asserted_multi_artists_1) + assert asserted_multi_artists_0 and asserted_multi_artists_1 class ImportExistingTest(ImportTestCase): @@ -806,30 +790,30 @@ def tearDown(self): def test_does_not_duplicate_item(self): self.importer.run() - self.assertEqual(len(self.lib.items()), 1) + assert len(self.lib.items()) == 1 self.reimporter.add_choice(importer.action.APPLY) self.reimporter.run() - self.assertEqual(len(self.lib.items()), 1) + assert len(self.lib.items()) == 1 def test_does_not_duplicate_album(self): self.importer.run() - self.assertEqual(len(self.lib.albums()), 1) + assert len(self.lib.albums()) == 1 self.reimporter.add_choice(importer.action.APPLY) self.reimporter.run() - self.assertEqual(len(self.lib.albums()), 1) + assert len(self.lib.albums()) == 1 def test_does_not_duplicate_singleton_track(self): self.importer.add_choice(importer.action.TRACKS) self.importer.add_choice(importer.action.APPLY) self.importer.run() - self.assertEqual(len(self.lib.items()), 1) + assert len(self.lib.items()) == 1 self.reimporter.add_choice(importer.action.TRACKS) self.reimporter.add_choice(importer.action.APPLY) self.reimporter.run() - self.assertEqual(len(self.lib.items()), 1) + assert len(self.lib.items()) == 1 def test_asis_updates_metadata(self): self.importer.run() @@ -839,7 +823,7 @@ def test_asis_updates_metadata(self): self.reimporter.add_choice(importer.action.ASIS) self.reimporter.run() - self.assertEqual(self.lib.items().get().title, "New Title") + assert self.lib.items().get().title == "New Title" def test_asis_updated_moves_file(self): self.importer.run() @@ -934,7 +918,7 @@ def test_add_album_for_different_artist_and_different_album(self): self.importer.run() albums = {album.album for album in self.lib.albums()} - self.assertEqual(albums, {"Album B", "Tag Album"}) + assert albums == {"Album B", "Tag Album"} def test_add_album_for_different_artist_and_same_albumartist(self): self.import_media[0].artist = "Artist B" @@ -946,7 +930,7 @@ def test_add_album_for_different_artist_and_same_albumartist(self): self.importer.run() artists = {album.albumartist for album in self.lib.albums()} - self.assertEqual(artists, {"Album Artist", "Tag Artist"}) + assert artists == {"Album Artist", "Tag Artist"} def test_add_album_for_same_artist_and_different_album(self): self.import_media[0].album = "Album B" @@ -954,7 +938,7 @@ def test_add_album_for_same_artist_and_different_album(self): self.importer.run() albums = {album.album for album in self.lib.albums()} - self.assertEqual(albums, {"Album B", "Tag Album"}) + assert albums == {"Album B", "Tag Album"} def test_add_album_for_same_album_and_different_artist(self): self.import_media[0].artist = "Artist B" @@ -962,7 +946,7 @@ def test_add_album_for_same_album_and_different_artist(self): self.importer.run() artists = {album.albumartist for album in self.lib.albums()} - self.assertEqual(artists, {"Artist B", "Tag Artist"}) + assert artists == {"Artist B", "Tag Artist"} def test_incremental(self): config["import"]["incremental"] = True @@ -971,7 +955,7 @@ def test_incremental(self): self.importer.run() albums = {album.album for album in self.lib.albums()} - self.assertEqual(albums, {"Album B", "Tag Album"}) + assert albums == {"Album B", "Tag Album"} class GlobalGroupAlbumsImportTest(GroupAlbumsImportTest): @@ -997,12 +981,12 @@ def tearDown(self): def test_choose_first_candidate(self): self.importer.add_choice(1) self.importer.run() - self.assertEqual(self.lib.albums().get().album, "Applied Album M") + assert self.lib.albums().get().album == "Applied Album M" def test_choose_second_candidate(self): self.importer.add_choice(2) self.importer.run() - self.assertEqual(self.lib.albums().get().album, "Applied Album MM") + assert self.lib.albums().get().album == "Applied Album MM" class InferAlbumDataTest(BeetsTestCase): @@ -1027,8 +1011,8 @@ def setUp(self): def test_asis_homogenous_single_artist(self): self.task.set_choice(importer.action.ASIS) self.task.align_album_level_fields() - self.assertFalse(self.items[0].comp) - self.assertEqual(self.items[0].albumartist, self.items[2].artist) + assert not self.items[0].comp + assert self.items[0].albumartist == self.items[2].artist def test_asis_heterogenous_va(self): self.items[0].artist = "another artist" @@ -1037,8 +1021,8 @@ def test_asis_heterogenous_va(self): self.task.align_album_level_fields() - self.assertTrue(self.items[0].comp) - self.assertEqual(self.items[0].albumartist, "Various Artists") + assert self.items[0].comp + assert self.items[0].albumartist == "Various Artists" def test_asis_comp_applied_to_all_items(self): self.items[0].artist = "another artist" @@ -1048,8 +1032,8 @@ def test_asis_comp_applied_to_all_items(self): self.task.align_album_level_fields() for item in self.items: - self.assertTrue(item.comp) - self.assertEqual(item.albumartist, "Various Artists") + assert item.comp + assert item.albumartist == "Various Artists" def test_asis_majority_artist_single_artist(self): self.items[0].artist = "another artist" @@ -1057,8 +1041,8 @@ def test_asis_majority_artist_single_artist(self): self.task.align_album_level_fields() - self.assertFalse(self.items[0].comp) - self.assertEqual(self.items[0].albumartist, self.items[2].artist) + assert not self.items[0].comp + assert self.items[0].albumartist == self.items[2].artist def test_asis_track_albumartist_override(self): self.items[0].artist = "another artist" @@ -1070,18 +1054,16 @@ def test_asis_track_albumartist_override(self): self.task.align_album_level_fields() - self.assertEqual(self.items[0].albumartist, "some album artist") - self.assertEqual(self.items[0].mb_albumartistid, "some album artist id") + assert self.items[0].albumartist == "some album artist" + assert self.items[0].mb_albumartistid == "some album artist id" def test_apply_gets_artist_and_id(self): self.task.set_choice(AlbumMatch(0, None, {}, set(), set())) # APPLY self.task.align_album_level_fields() - self.assertEqual(self.items[0].albumartist, self.items[0].artist) - self.assertEqual( - self.items[0].mb_albumartistid, self.items[0].mb_artistid - ) + assert self.items[0].albumartist == self.items[0].artist + assert self.items[0].mb_albumartistid == self.items[0].mb_artistid def test_apply_lets_album_values_override(self): for item in self.items: @@ -1091,15 +1073,15 @@ def test_apply_lets_album_values_override(self): self.task.align_album_level_fields() - self.assertEqual(self.items[0].albumartist, "some album artist") - self.assertEqual(self.items[0].mb_albumartistid, "some album artist id") + assert self.items[0].albumartist == "some album artist" + assert self.items[0].mb_albumartistid == "some album artist id" def test_small_single_artist_album(self): self.items = [self.items[0]] self.task.items = self.items self.task.set_choice(importer.action.ASIS) self.task.align_album_level_fields() - self.assertFalse(self.items[0].comp) + assert not self.items[0].comp def match_album_mock(*args, **kwargs): @@ -1136,22 +1118,22 @@ def setUp(self): def test_remove_duplicate_album(self): item = self.lib.items().get() - self.assertEqual(item.title, "t\xeftle 0") + assert item.title == "t\xeftle 0" self.assertExists(item.path) self.importer.default_resolution = self.importer.Resolution.REMOVE self.importer.run() self.assertNotExists(item.path) - self.assertEqual(len(self.lib.albums()), 1) - self.assertEqual(len(self.lib.items()), 1) + assert len(self.lib.albums()) == 1 + assert len(self.lib.items()) == 1 item = self.lib.items().get() - self.assertEqual(item.title, "new title") + assert item.title == "new title" def test_no_autotag_keeps_duplicate_album(self): config["import"]["autotag"] = False item = self.lib.items().get() - self.assertEqual(item.title, "t\xeftle 0") + assert item.title == "t\xeftle 0" self.assertExists(item.path) # Imported item has the same artist and album as the one in the @@ -1169,33 +1151,33 @@ def test_no_autotag_keeps_duplicate_album(self): self.importer.run() self.assertExists(item.path) - self.assertEqual(len(self.lib.albums()), 2) - self.assertEqual(len(self.lib.items()), 2) + assert len(self.lib.albums()) == 2 + assert len(self.lib.items()) == 2 def test_keep_duplicate_album(self): self.importer.default_resolution = self.importer.Resolution.KEEPBOTH self.importer.run() - self.assertEqual(len(self.lib.albums()), 2) - self.assertEqual(len(self.lib.items()), 2) + assert len(self.lib.albums()) == 2 + assert len(self.lib.items()) == 2 def test_skip_duplicate_album(self): item = self.lib.items().get() - self.assertEqual(item.title, "t\xeftle 0") + assert item.title == "t\xeftle 0" self.importer.default_resolution = self.importer.Resolution.SKIP self.importer.run() - self.assertEqual(len(self.lib.albums()), 1) - self.assertEqual(len(self.lib.items()), 1) + assert len(self.lib.albums()) == 1 + assert len(self.lib.items()) == 1 item = self.lib.items().get() - self.assertEqual(item.title, "t\xeftle 0") + assert item.title == "t\xeftle 0" def test_merge_duplicate_album(self): self.importer.default_resolution = self.importer.Resolution.MERGE self.importer.run() - self.assertEqual(len(self.lib.albums()), 1) + assert len(self.lib.albums()) == 1 def test_twice_in_import_dir(self): self.skipTest("write me") @@ -1216,8 +1198,8 @@ def test_keep_when_extra_key_is_different(self): self.importer.default_resolution = self.importer.Resolution.SKIP self.importer.run() - self.assertEqual(len(self.lib.albums()), 2) - self.assertEqual(len(self.lib.items()), 2) + assert len(self.lib.albums()) == 2 + assert len(self.lib.items()) == 2 def add_album_fixture(self, **kwargs): # TODO move this into upstream @@ -1258,47 +1240,47 @@ def setUp(self): def test_remove_duplicate(self): item = self.lib.items().get() - self.assertEqual(item.mb_trackid, "old trackid") + assert item.mb_trackid == "old trackid" self.assertExists(item.path) self.importer.default_resolution = self.importer.Resolution.REMOVE self.importer.run() self.assertNotExists(item.path) - self.assertEqual(len(self.lib.items()), 1) + assert len(self.lib.items()) == 1 item = self.lib.items().get() - self.assertEqual(item.mb_trackid, "new trackid") + assert item.mb_trackid == "new trackid" def test_keep_duplicate(self): - self.assertEqual(len(self.lib.items()), 1) + assert len(self.lib.items()) == 1 self.importer.default_resolution = self.importer.Resolution.KEEPBOTH self.importer.run() - self.assertEqual(len(self.lib.items()), 2) + assert len(self.lib.items()) == 2 def test_skip_duplicate(self): item = self.lib.items().get() - self.assertEqual(item.mb_trackid, "old trackid") + assert item.mb_trackid == "old trackid" self.importer.default_resolution = self.importer.Resolution.SKIP self.importer.run() - self.assertEqual(len(self.lib.items()), 1) + assert len(self.lib.items()) == 1 item = self.lib.items().get() - self.assertEqual(item.mb_trackid, "old trackid") + assert item.mb_trackid == "old trackid" def test_keep_when_extra_key_is_different(self): config["import"]["duplicate_keys"]["item"] = "artist title flex" item = self.lib.items().get() item.flex = "different" item.store() - self.assertEqual(len(self.lib.items()), 1) + assert len(self.lib.items()) == 1 self.importer.default_resolution = self.importer.Resolution.SKIP self.importer.run() - self.assertEqual(len(self.lib.items()), 2) + assert len(self.lib.items()) == 2 def test_twice_in_import_dir(self): self.skipTest("write me") @@ -1317,14 +1299,14 @@ def test_tag_log_line(self): handler = logging.StreamHandler(sio) session = _common.import_session(loghandler=handler) session.tag_log("status", "path") - self.assertIn("status path", sio.getvalue()) + assert "status path" in sio.getvalue() def test_tag_log_unicode(self): sio = StringIO() handler = logging.StreamHandler(sio) session = _common.import_session(loghandler=handler) session.tag_log("status", "caf\xe9") # send unicode - self.assertIn("status caf\xe9", sio.getvalue()) + assert "status caf\xe9" in sio.getvalue() class ResumeImportTest(ImportTestCase): @@ -1342,12 +1324,12 @@ def raise_exception(event, **kwargs): plugins_send.side_effect = raise_exception self.importer.run() - self.assertEqual(len(self.lib.albums()), 1) - self.assertIsNotNone(self.lib.albums("album:'Album 1'").get()) + assert len(self.lib.albums()) == 1 + assert self.lib.albums("album:'Album 1'").get() is not None self.importer.run() - self.assertEqual(len(self.lib.albums()), 2) - self.assertIsNotNone(self.lib.albums("album:'Album 2'").get()) + assert len(self.lib.albums()) == 2 + assert self.lib.albums("album:'Album 2'").get() is not None @patch("beets.plugins.send") def test_resume_singleton(self, plugins_send): @@ -1365,12 +1347,12 @@ def raise_exception(event, **kwargs): plugins_send.side_effect = raise_exception self.importer.run() - self.assertEqual(len(self.lib.items()), 1) - self.assertIsNotNone(self.lib.items("title:'Track 1'").get()) + assert len(self.lib.items()) == 1 + assert self.lib.items("title:'Track 1'").get() is not None self.importer.run() - self.assertEqual(len(self.lib.items()), 2) - self.assertIsNotNone(self.lib.items("title:'Track 1'").get()) + assert len(self.lib.items()) == 2 + assert self.lib.items("title:'Track 1'").get() is not None class IncrementalImportTest(AsIsImporterMixin, ImportTestCase): @@ -1384,7 +1366,7 @@ def test_incremental_album(self): album.store() importer.run() - self.assertEqual(len(self.lib.albums()), 2) + assert len(self.lib.albums()) == 2 def test_incremental_item(self): importer = self.run_asis_importer(incremental=True, singletons=True) @@ -1396,13 +1378,13 @@ def test_incremental_item(self): item.store() importer.run() - self.assertEqual(len(self.lib.items()), 2) + assert len(self.lib.items()) == 2 def test_invalid_state_file(self): with open(self.config["statefile"].as_filename(), "wb") as f: f.write(b"000") self.run_asis_importer(incremental=True) - self.assertEqual(len(self.lib.albums()), 1) + assert len(self.lib.albums()) == 1 def _mkmp3(path): @@ -1434,24 +1416,24 @@ def setUp(self): def test_finds_all_albums(self): albums = list(albums_in_dir(self.base)) - self.assertEqual(len(albums), 4) + assert len(albums) == 4 def test_separates_contents(self): found = [] for _, album in albums_in_dir(self.base): found.append(re.search(rb"album(.)song", album[0]).group(1)) - self.assertIn(b"1", found) - self.assertIn(b"2", found) - self.assertIn(b"3", found) - self.assertIn(b"4", found) + assert b"1" in found + assert b"2" in found + assert b"3" in found + assert b"4" in found def test_finds_multiple_songs(self): for _, album in albums_in_dir(self.base): n = re.search(rb"album(.)song", album[0]).group(1) if n == b"1": - self.assertEqual(len(album), 2) + assert len(album) == 2 else: - self.assertEqual(len(album), 1) + assert len(album) == 1 class MultiDiscAlbumsInDirTest(BeetsTestCase): @@ -1527,51 +1509,51 @@ def _normalize_path(self, path): def test_coalesce_nested_album_multiple_subdirs(self): self.create_music() albums = list(albums_in_dir(self.base)) - self.assertEqual(len(albums), 4) + assert len(albums) == 4 root, items = albums[0] - self.assertEqual(root, self.dirs[0:3]) - self.assertEqual(len(items), 3) + assert root == self.dirs[0:3] + assert len(items) == 3 def test_coalesce_nested_album_single_subdir(self): self.create_music() albums = list(albums_in_dir(self.base)) root, items = albums[1] - self.assertEqual(root, self.dirs[3:5]) - self.assertEqual(len(items), 1) + assert root == self.dirs[3:5] + assert len(items) == 1 def test_coalesce_flattened_album_case_typo(self): self.create_music() albums = list(albums_in_dir(self.base)) root, items = albums[2] - self.assertEqual(root, self.dirs[6:8]) - self.assertEqual(len(items), 2) + assert root == self.dirs[6:8] + assert len(items) == 2 def test_single_disc_album(self): self.create_music() albums = list(albums_in_dir(self.base)) root, items = albums[3] - self.assertEqual(root, self.dirs[8:]) - self.assertEqual(len(items), 1) + assert root == self.dirs[8:] + assert len(items) == 1 def test_do_not_yield_empty_album(self): self.create_music(files=False) albums = list(albums_in_dir(self.base)) - self.assertEqual(len(albums), 0) + assert len(albums) == 0 def test_single_disc_unicode(self): self.create_music(ascii=False) albums = list(albums_in_dir(self.base)) root, items = albums[3] - self.assertEqual(root, self.dirs[8:]) - self.assertEqual(len(items), 1) + assert root == self.dirs[8:] + assert len(items) == 1 def test_coalesce_multiple_unicode(self): self.create_music(ascii=False) albums = list(albums_in_dir(self.base)) - self.assertEqual(len(albums), 4) + assert len(albums) == 4 root, items = albums[0] - self.assertEqual(root, self.dirs[0:3]) - self.assertEqual(len(items), 3) + assert root == self.dirs[0:3] + assert len(items) == 3 class ReimportTest(ImportTestCase): @@ -1617,45 +1599,45 @@ def _item(self): def test_reimported_album_gets_new_metadata(self): self._setup_session() - self.assertEqual(self._album().album, "\xe4lbum") + assert self._album().album == "\xe4lbum" self.importer.run() - self.assertEqual(self._album().album, "the album") + assert self._album().album == "the album" def test_reimported_album_preserves_flexattr(self): self._setup_session() self.importer.run() - self.assertEqual(self._album().foo, "bar") + assert self._album().foo == "bar" def test_reimported_album_preserves_added(self): self._setup_session() self.importer.run() - self.assertEqual(self._album().added, 4242.0) + assert self._album().added == 4242.0 def test_reimported_album_preserves_item_flexattr(self): self._setup_session() self.importer.run() - self.assertEqual(self._item().baz, "qux") + assert self._item().baz == "qux" def test_reimported_album_preserves_item_added(self): self._setup_session() self.importer.run() - self.assertEqual(self._item().added, 4747.0) + assert self._item().added == 4747.0 def test_reimported_item_gets_new_metadata(self): self._setup_session(True) - self.assertEqual(self._item().title, "t\xeftle 0") + assert self._item().title == "t\xeftle 0" self.importer.run() - self.assertEqual(self._item().title, "full") + assert self._item().title == "full" def test_reimported_item_preserves_flexattr(self): self._setup_session(True) self.importer.run() - self.assertEqual(self._item().baz, "qux") + assert self._item().baz == "qux" def test_reimported_item_preserves_added(self): self._setup_session(True) self.importer.run() - self.assertEqual(self._item().added, 4747.0) + assert self._item().added == 4747.0 def test_reimported_item_preserves_art(self): self._setup_session() @@ -1667,16 +1649,16 @@ def test_reimported_item_preserves_art(self): self.importer.run() new_album = self._album() new_artpath = new_album.art_destination(art_source) - self.assertEqual(new_album.artpath, new_artpath) + assert new_album.artpath == new_artpath self.assertExists(new_artpath) if new_artpath != old_artpath: self.assertNotExists(old_artpath) def test_reimported_album_not_preserves_flexattr(self): self._setup_session() - self.assertEqual(self._album().data_source, "original_source") + assert self._album().data_source == "original_source" self.importer.run() - self.assertEqual(self._album().data_source, "match_source") + assert self._album().data_source == "match_source" class ImportPretendTest(ImportTestCase): @@ -1699,30 +1681,24 @@ def __run(self, importer): with capture_log() as logs: importer.run() - self.assertEqual(len(self.lib.items()), 0) - self.assertEqual(len(self.lib.albums()), 0) + assert len(self.lib.items()) == 0 + assert len(self.lib.albums()) == 0 return [line for line in logs if not line.startswith("Sending event:")] def test_import_singletons_pretend(self): - self.assertEqual( - self.__run(self.setup_singleton_importer(pretend=True)), - [ - f"Singleton: {self.single_path}", - f"Singleton: {self.album_track_path}", - ], - ) + assert self.__run(self.setup_singleton_importer(pretend=True)) == [ + f"Singleton: {self.single_path}", + f"Singleton: {self.album_track_path}", + ] def test_import_album_pretend(self): - self.assertEqual( - self.__run(self.setup_importer(pretend=True)), - [ - f"Album: {self.import_path}", - f" {self.single_path}", - f"Album: {self.album_path}", - f" {self.album_track_path}", - ], - ) + assert self.__run(self.setup_importer(pretend=True)) == [ + f"Album: {self.import_path}", + f" {self.single_path}", + f"Album: {self.album_path}", + f" {self.album_track_path}", + ] def test_import_pretend_empty(self): empty_path = Path(os.fsdecode(self.temp_dir)) / "empty" @@ -1730,10 +1706,7 @@ def test_import_pretend_empty(self): importer = self.setup_importer(pretend=True, import_dir=empty_path) - self.assertEqual( - self.__run(importer), - [f"No files imported from {empty_path}"], - ) + assert self.__run(importer) == [f"No files imported from {empty_path}"] # Helpers for ImportMusicBrainzIdTest. @@ -1858,7 +1831,7 @@ def test_one_mbid_one_album(self): self.importer.add_choice(importer.action.APPLY) self.importer.run() - self.assertEqual(self.lib.albums().get().album, "VALID_RELEASE_0") + assert self.lib.albums().get().album == "VALID_RELEASE_0" def test_several_mbid_one_album(self): self.setup_importer( @@ -1871,7 +1844,7 @@ def test_several_mbid_one_album(self): self.importer.add_choice(2) # Pick the 2nd best match (release 1). self.importer.add_choice(importer.action.APPLY) self.importer.run() - self.assertEqual(self.lib.albums().get().album, "VALID_RELEASE_1") + assert self.lib.albums().get().album == "VALID_RELEASE_1" def test_one_mbid_one_singleton(self): self.setup_singleton_importer( @@ -1880,7 +1853,7 @@ def test_one_mbid_one_singleton(self): self.importer.add_choice(importer.action.APPLY) self.importer.run() - self.assertEqual(self.lib.items().get().title, "VALID_RECORDING_0") + assert self.lib.items().get().title == "VALID_RECORDING_0" def test_several_mbid_one_singleton(self): self.setup_singleton_importer( @@ -1893,7 +1866,7 @@ def test_several_mbid_one_singleton(self): self.importer.add_choice(2) # Pick the 2nd best match (recording 1). self.importer.add_choice(importer.action.APPLY) self.importer.run() - self.assertEqual(self.lib.items().get().title, "VALID_RECORDING_1") + assert self.lib.items().get().title == "VALID_RECORDING_1" def test_candidates_album(self): """Test directly ImportTask.lookup_candidates().""" @@ -1907,10 +1880,9 @@ def test_candidates_album(self): ] task.lookup_candidates() - self.assertEqual( - {"VALID_RELEASE_0", "VALID_RELEASE_1"}, - {c.info.album for c in task.candidates}, - ) + assert {"VALID_RELEASE_0", "VALID_RELEASE_1"} == { + c.info.album for c in task.candidates + } def test_candidates_singleton(self): """Test directly SingletonImportTask.lookup_candidates().""" @@ -1924,7 +1896,6 @@ def test_candidates_singleton(self): ] task.lookup_candidates() - self.assertEqual( - {"VALID_RECORDING_0", "VALID_RECORDING_1"}, - {c.info.title for c in task.candidates}, - ) + assert {"VALID_RECORDING_0", "VALID_RECORDING_1"} == { + c.info.title for c in task.candidates + } diff --git a/test/test_library.py b/test/test_library.py index 3e35a44a02..4e9c50b44e 100644 --- a/test/test_library.py +++ b/test/test_library.py @@ -12,8 +12,7 @@ # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. -"""Tests for non-query database functions of Item. -""" +"""Tests for non-query database functions of Item.""" import os import os.path @@ -25,6 +24,7 @@ import unicodedata import unittest +import pytest from mediafile import MediaFile, UnreadableFileError import beets.dbcore.query @@ -44,13 +44,13 @@ def test_load_restores_data_from_db(self): original_title = self.i.title self.i.title = "something" self.i.load() - self.assertEqual(original_title, self.i.title) + assert original_title == self.i.title def test_load_clears_dirty_flags(self): self.i.artist = "something" - self.assertIn("artist", self.i._dirty) + assert "artist" in self.i._dirty self.i.load() - self.assertNotIn("artist", self.i._dirty) + assert "artist" not in self.i._dirty class StoreTest(ItemInDBTestCase): @@ -62,7 +62,7 @@ def test_store_changes_database_value(self): .execute("select year from items where " 'title="the title"') .fetchone()["year"] ) - self.assertEqual(new_year, 1987) + assert new_year == 1987 def test_store_only_writes_dirty_fields(self): original_genre = self.i.genre @@ -73,12 +73,12 @@ def test_store_only_writes_dirty_fields(self): .execute("select genre from items where " 'title="the title"') .fetchone()["genre"] ) - self.assertEqual(new_genre, original_genre) + assert new_genre == original_genre def test_store_clears_dirty_flags(self): self.i.composer = "tvp" self.i.store() - self.assertNotIn("composer", self.i._dirty) + assert "composer" not in self.i._dirty def test_store_album_cascades_flex_deletes(self): album = _common.album() @@ -90,8 +90,8 @@ def test_store_album_cascades_flex_deletes(self): self.lib.add(item) del album.flex1 album.store() - self.assertNotIn("flex1", album) - self.assertNotIn("flex1", album.items()[0]) + assert "flex1" not in album + assert "flex1" not in album.items()[0] class AddTest(BeetsTestCase): @@ -108,7 +108,7 @@ def test_item_add_inserts_row(self): ) .fetchone()["grouping"] ) - self.assertEqual(new_grouping, self.i.grouping) + assert new_grouping == self.i.grouping def test_library_add_path_inserts_row(self): i = beets.library.Item.from_path( @@ -122,14 +122,14 @@ def test_library_add_path_inserts_row(self): ) .fetchone()["grouping"] ) - self.assertEqual(new_grouping, self.i.grouping) + assert new_grouping == self.i.grouping class RemoveTest(ItemInDBTestCase): def test_remove_deletes_from_db(self): self.i.remove() c = self.lib._connection().execute("select * from items") - self.assertIsNone(c.fetchone()) + assert c.fetchone() is None class GetSetTest(BeetsTestCase): @@ -139,18 +139,19 @@ def setUp(self): def test_set_changes_value(self): self.i.bpm = 4915 - self.assertEqual(self.i.bpm, 4915) + assert self.i.bpm == 4915 def test_set_sets_dirty_flag(self): self.i.comp = not self.i.comp - self.assertIn("comp", self.i._dirty) + assert "comp" in self.i._dirty def test_set_does_not_dirty_if_value_unchanged(self): self.i.title = self.i.title - self.assertNotIn("title", self.i._dirty) + assert "title" not in self.i._dirty def test_invalid_field_raises_attributeerror(self): - self.assertRaises(AttributeError, getattr, self.i, "xyzzy") + with pytest.raises(AttributeError): + self.i.xyzzy def test_album_fallback(self): # integration test of item-album fallback @@ -159,12 +160,12 @@ def test_album_fallback(self): album["flex"] = "foo" album.store() - self.assertIn("flex", i) - self.assertNotIn("flex", i.keys(with_album=False)) - self.assertEqual(i["flex"], "foo") - self.assertEqual(i.get("flex"), "foo") - self.assertIsNone(i.get("flex", with_album=False)) - self.assertIsNone(i.get("flexx")) + assert "flex" in i + assert "flex" not in i.keys(with_album=False) + assert i["flex"] == "foo" + assert i.get("flex") == "foo" + assert i.get("flex", with_album=False) is None + assert i.get("flexx") is None class DestinationTest(BeetsTestCase): @@ -181,12 +182,12 @@ def setUp(self): def test_directory_works_with_trailing_slash(self): self.lib.directory = b"one/" self.lib.path_formats = [("default", "two")] - self.assertEqual(self.i.destination(), np("one/two")) + assert self.i.destination() == np("one/two") def test_directory_works_without_trailing_slash(self): self.lib.directory = b"one" self.lib.path_formats = [("default", "two")] - self.assertEqual(self.i.destination(), np("one/two")) + assert self.i.destination() == np("one/two") def test_destination_substitutes_metadata_values(self): self.lib.directory = b"base" @@ -194,19 +195,19 @@ def test_destination_substitutes_metadata_values(self): self.i.title = "three" self.i.artist = "two" self.i.album = "one" - self.assertEqual(self.i.destination(), np("base/one/two three")) + assert self.i.destination() == np("base/one/two three") def test_destination_preserves_extension(self): self.lib.directory = b"base" self.lib.path_formats = [("default", "$title")] self.i.path = "hey.audioformat" - self.assertEqual(self.i.destination(), np("base/the title.audioformat")) + assert self.i.destination() == np("base/the title.audioformat") def test_lower_case_extension(self): self.lib.directory = b"base" self.lib.path_formats = [("default", "$title")] self.i.path = "hey.MP3" - self.assertEqual(self.i.destination(), np("base/the title.mp3")) + assert self.i.destination() == np("base/the title.mp3") def test_destination_pads_some_indices(self): self.lib.directory = b"base" @@ -218,7 +219,7 @@ def test_destination_pads_some_indices(self): self.i.disc = 3 self.i.disctotal = 4 self.i.bpm = 5 - self.assertEqual(self.i.destination(), np("base/01 02 03 04 5")) + assert self.i.destination() == np("base/01 02 03 04 5") def test_destination_pads_date_values(self): self.lib.directory = b"base" @@ -226,52 +227,52 @@ def test_destination_pads_date_values(self): self.i.year = 1 self.i.month = 2 self.i.day = 3 - self.assertEqual(self.i.destination(), np("base/0001-02-03")) + assert self.i.destination() == np("base/0001-02-03") def test_destination_escapes_slashes(self): self.i.album = "one/two" dest = self.i.destination() - self.assertIn(b"one", dest) - self.assertIn(b"two", dest) - self.assertNotIn(b"one/two", dest) + assert b"one" in dest + assert b"two" in dest + assert b"one/two" not in dest def test_destination_escapes_leading_dot(self): self.i.album = ".something" dest = self.i.destination() - self.assertIn(b"something", dest) - self.assertNotIn(b"/.something", dest) + assert b"something" in dest + assert b"/.something" not in dest def test_destination_preserves_legitimate_slashes(self): self.i.artist = "one" self.i.album = "two" dest = self.i.destination() - self.assertIn(os.path.join(b"one", b"two"), dest) + assert os.path.join(b"one", b"two") in dest def test_destination_long_names_truncated(self): self.i.title = "X" * 300 self.i.artist = "Y" * 300 for c in self.i.destination().split(util.PATH_SEP): - self.assertLessEqual(len(c), 255) + assert len(c) <= 255 def test_destination_long_names_keep_extension(self): self.i.title = "X" * 300 self.i.path = b"something.extn" dest = self.i.destination() - self.assertEqual(dest[-5:], b".extn") + assert dest[-5:] == b".extn" def test_distination_windows_removes_both_separators(self): self.i.title = "one \\ two / three.mp3" with _common.platform_windows(): p = self.i.destination() - self.assertNotIn(b"one \\ two", p) - self.assertNotIn(b"one / two", p) - self.assertNotIn(b"two \\ three", p) - self.assertNotIn(b"two / three", p) + assert b"one \\ two" not in p + assert b"one / two" not in p + assert b"two \\ three" not in p + assert b"two / three" not in p def test_path_with_format(self): self.lib.path_formats = [("default", "$artist/$album ($format)")] p = self.i.destination() - self.assertIn(b"(FLAC)", p) + assert b"(FLAC)" in p def test_heterogeneous_album_gets_single_directory(self): i1, i2 = item(), item() @@ -279,14 +280,14 @@ def test_heterogeneous_album_gets_single_directory(self): i1.year, i2.year = 2009, 2010 self.lib.path_formats = [("default", "$album ($year)/$track $title")] dest1, dest2 = i1.destination(), i2.destination() - self.assertEqual(os.path.dirname(dest1), os.path.dirname(dest2)) + assert os.path.dirname(dest1) == os.path.dirname(dest2) def test_default_path_for_non_compilations(self): self.i.comp = False self.lib.add_album([self.i]) self.lib.directory = b"one" self.lib.path_formats = [("default", "two"), ("comp:true", "three")] - self.assertEqual(self.i.destination(), np("one/two")) + assert self.i.destination() == np("one/two") def test_singleton_path(self): i = item(self.lib) @@ -296,7 +297,7 @@ def test_singleton_path(self): ("singleton:true", "four"), ("comp:true", "three"), ] - self.assertEqual(i.destination(), np("one/four")) + assert i.destination() == np("one/four") def test_comp_before_singleton_path(self): i = item(self.lib) @@ -307,17 +308,14 @@ def test_comp_before_singleton_path(self): ("comp:true", "three"), ("singleton:true", "four"), ] - self.assertEqual(i.destination(), np("one/three")) + assert i.destination() == np("one/three") def test_comp_path(self): self.i.comp = True self.lib.add_album([self.i]) self.lib.directory = b"one" - self.lib.path_formats = [ - ("default", "two"), - ("comp:true", "three"), - ] - self.assertEqual(self.i.destination(), np("one/three")) + self.lib.path_formats = [("default", "two"), ("comp:true", "three")] + assert self.i.destination() == np("one/three") def test_albumtype_query_path(self): self.i.comp = True @@ -329,7 +327,7 @@ def test_albumtype_query_path(self): ("albumtype:sometype", "four"), ("comp:true", "three"), ] - self.assertEqual(self.i.destination(), np("one/four")) + assert self.i.destination() == np("one/four") def test_albumtype_path_fallback_to_comp(self): self.i.comp = True @@ -341,84 +339,84 @@ def test_albumtype_path_fallback_to_comp(self): ("albumtype:anothertype", "four"), ("comp:true", "three"), ] - self.assertEqual(self.i.destination(), np("one/three")) + assert self.i.destination() == np("one/three") def test_get_formatted_does_not_replace_separators(self): with _common.platform_posix(): name = os.path.join("a", "b") self.i.title = name newname = self.i.formatted().get("title") - self.assertEqual(name, newname) + assert name == newname def test_get_formatted_pads_with_zero(self): with _common.platform_posix(): self.i.track = 1 name = self.i.formatted().get("track") - self.assertTrue(name.startswith("0")) + assert name.startswith("0") def test_get_formatted_uses_kbps_bitrate(self): with _common.platform_posix(): self.i.bitrate = 12345 val = self.i.formatted().get("bitrate") - self.assertEqual(val, "12kbps") + assert val == "12kbps" def test_get_formatted_uses_khz_samplerate(self): with _common.platform_posix(): self.i.samplerate = 12345 val = self.i.formatted().get("samplerate") - self.assertEqual(val, "12kHz") + assert val == "12kHz" def test_get_formatted_datetime(self): with _common.platform_posix(): self.i.added = 1368302461.210265 val = self.i.formatted().get("added") - self.assertTrue(val.startswith("2013")) + assert val.startswith("2013") def test_get_formatted_none(self): with _common.platform_posix(): self.i.some_other_field = None val = self.i.formatted().get("some_other_field") - self.assertEqual(val, "") + assert val == "" def test_artist_falls_back_to_albumartist(self): self.i.artist = "" self.i.albumartist = "something" self.lib.path_formats = [("default", "$artist")] p = self.i.destination() - self.assertEqual(p.rsplit(util.PATH_SEP, 1)[1], b"something") + assert p.rsplit(util.PATH_SEP, 1)[1] == b"something" def test_albumartist_falls_back_to_artist(self): self.i.artist = "trackartist" self.i.albumartist = "" self.lib.path_formats = [("default", "$albumartist")] p = self.i.destination() - self.assertEqual(p.rsplit(util.PATH_SEP, 1)[1], b"trackartist") + assert p.rsplit(util.PATH_SEP, 1)[1] == b"trackartist" def test_artist_overrides_albumartist(self): self.i.artist = "theartist" self.i.albumartist = "something" self.lib.path_formats = [("default", "$artist")] p = self.i.destination() - self.assertEqual(p.rsplit(util.PATH_SEP, 1)[1], b"theartist") + assert p.rsplit(util.PATH_SEP, 1)[1] == b"theartist" def test_albumartist_overrides_artist(self): self.i.artist = "theartist" self.i.albumartist = "something" self.lib.path_formats = [("default", "$albumartist")] p = self.i.destination() - self.assertEqual(p.rsplit(util.PATH_SEP, 1)[1], b"something") + assert p.rsplit(util.PATH_SEP, 1)[1] == b"something" def test_unicode_normalized_nfd_on_mac(self): instr = unicodedata.normalize("NFC", "caf\xe9") self.lib.path_formats = [("default", instr)] dest = self.i.destination(platform="darwin", fragment=True) - self.assertEqual(dest, unicodedata.normalize("NFD", instr)) + assert dest == unicodedata.normalize("NFD", instr) def test_unicode_normalized_nfc_on_linux(self): instr = unicodedata.normalize("NFD", "caf\xe9") self.lib.path_formats = [("default", instr)] dest = self.i.destination(platform="linux", fragment=True) - self.assertEqual(dest, unicodedata.normalize("NFC", instr)) + assert dest == unicodedata.normalize("NFC", instr) def test_non_mbcs_characters_on_windows(self): oldfunc = sys.getfilesystemencoding @@ -427,9 +425,9 @@ def test_non_mbcs_characters_on_windows(self): self.i.title = "h\u0259d" self.lib.path_formats = [("default", "$title")] p = self.i.destination() - self.assertNotIn(b"?", p) + assert b"?" not in p # We use UTF-8 to encode Windows paths now. - self.assertIn("h\u0259d".encode(), p) + assert "h\u0259d".encode() in p finally: sys.getfilesystemencoding = oldfunc @@ -437,7 +435,7 @@ def test_unicode_extension_in_fragment(self): self.lib.path_formats = [("default", "foo")] self.i.path = util.bytestring_path("bar.caf\xe9") dest = self.i.destination(platform="linux", fragment=True) - self.assertEqual(dest, "foo.caf\xe9") + assert dest == "foo.caf\xe9" def test_asciify_and_replace(self): config["asciify_paths"] = True @@ -445,14 +443,14 @@ def test_asciify_and_replace(self): self.lib.directory = b"lib" self.lib.path_formats = [("default", "$title")] self.i.title = "\u201c\u00f6\u2014\u00cf\u201d" - self.assertEqual(self.i.destination(), np("lib/qo--Iq")) + assert self.i.destination() == np("lib/qo--Iq") def test_asciify_character_expanding_to_slash(self): config["asciify_paths"] = True self.lib.directory = b"lib" self.lib.path_formats = [("default", "$title")] self.i.title = "ab\xa2\xbdd" - self.assertEqual(self.i.destination(), np("lib/abC_ 1_2d")) + assert self.i.destination() == np("lib/abC_ 1_2d") def test_destination_with_replacements(self): self.lib.directory = b"base" @@ -460,7 +458,7 @@ def test_destination_with_replacements(self): self.lib.path_formats = [("default", "$album/$title")] self.i.title = "foo" self.i.album = "bar" - self.assertEqual(self.i.destination(), np("base/ber/foo")) + assert self.i.destination() == np("base/ber/foo") def test_destination_with_replacements_argument(self): self.lib.directory = b"base" @@ -469,8 +467,8 @@ def test_destination_with_replacements_argument(self): self.i.title = "foo" self.i.album = "bar" replacements = [(re.compile(r"a"), "e")] - self.assertEqual( - self.i.destination(replacements=replacements), np("base/ber/foo") + assert self.i.destination(replacements=replacements) == np( + "base/ber/foo" ) @unittest.skip("unimplemented: #359") @@ -482,7 +480,7 @@ def test_destination_with_empty_component(self): self.i.artist = "" self.i.albumartist = "" self.i.album = "one" - self.assertEqual(self.i.destination(), np("base/one/_/three")) + assert self.i.destination() == np("base/one/_/three") @unittest.skip("unimplemented: #359") def test_destination_with_empty_final_component(self): @@ -492,7 +490,7 @@ def test_destination_with_empty_final_component(self): self.i.title = "" self.i.album = "one" self.i.path = "foo.mp3" - self.assertEqual(self.i.destination(), np("base/one/_.mp3")) + assert self.i.destination() == np("base/one/_.mp3") def test_legalize_path_one_for_one_replacement(self): # Use a replacement that should always replace the last X in any @@ -507,7 +505,7 @@ def test_legalize_path_one_for_one_replacement(self): # The final path should reflect the replacement. dest = self.i.destination() - self.assertEqual(dest[-2:], b"XZ") + assert dest[-2:] == b"XZ" def test_legalize_path_one_for_many_replacement(self): # Use a replacement that should always replace the last X in any @@ -523,16 +521,16 @@ def test_legalize_path_one_for_many_replacement(self): # The final path should ignore the user replacement and create a path # of the correct length, containing Xs. dest = self.i.destination() - self.assertEqual(dest[-2:], b"XX") + assert dest[-2:] == b"XX" def test_album_field_query(self): self.lib.directory = b"one" self.lib.path_formats = [("default", "two"), ("flex:foo", "three")] album = self.lib.add_album([self.i]) - self.assertEqual(self.i.destination(), np("one/two")) + assert self.i.destination() == np("one/two") album["flex"] = "foo" album.store() - self.assertEqual(self.i.destination(), np("one/three")) + assert self.i.destination() == np("one/three") def test_album_field_in_template(self): self.lib.directory = b"one" @@ -540,38 +538,38 @@ def test_album_field_in_template(self): album = self.lib.add_album([self.i]) album["flex"] = "foo" album.store() - self.assertEqual(self.i.destination(), np("one/foo/two")) + assert self.i.destination() == np("one/foo/two") class ItemFormattedMappingTest(ItemInDBTestCase): def test_formatted_item_value(self): formatted = self.i.formatted() - self.assertEqual(formatted["artist"], "the artist") + assert formatted["artist"] == "the artist" def test_get_unset_field(self): formatted = self.i.formatted() - with self.assertRaises(KeyError): + with pytest.raises(KeyError): formatted["other_field"] def test_get_method_with_default(self): formatted = self.i.formatted() - self.assertEqual(formatted.get("other_field"), "") + assert formatted.get("other_field") == "" def test_get_method_with_specified_default(self): formatted = self.i.formatted() - self.assertEqual(formatted.get("other_field", "default"), "default") + assert formatted.get("other_field", "default") == "default" def test_item_precedence(self): album = self.lib.add_album([self.i]) album["artist"] = "foo" album.store() - self.assertNotEqual("foo", self.i.formatted().get("artist")) + assert "foo" != self.i.formatted().get("artist") def test_album_flex_field(self): album = self.lib.add_album([self.i]) album["flex"] = "foo" album.store() - self.assertEqual("foo", self.i.formatted().get("flex")) + assert "foo" == self.i.formatted().get("flex") def test_album_field_overrides_item_field_for_path(self): # Make the album inconsistent with the item. @@ -583,23 +581,23 @@ def test_album_field_overrides_item_field_for_path(self): # Ensure the album takes precedence. formatted = self.i.formatted(for_path=True) - self.assertEqual(formatted["album"], "foo") + assert formatted["album"] == "foo" def test_artist_falls_back_to_albumartist(self): self.i.artist = "" formatted = self.i.formatted() - self.assertEqual(formatted["artist"], "the album artist") + assert formatted["artist"] == "the album artist" def test_albumartist_falls_back_to_artist(self): self.i.albumartist = "" formatted = self.i.formatted() - self.assertEqual(formatted["albumartist"], "the artist") + assert formatted["albumartist"] == "the artist" def test_both_artist_and_albumartist_empty(self): self.i.artist = "" self.i.albumartist = "" formatted = self.i.formatted() - self.assertEqual(formatted["albumartist"], "") + assert formatted["albumartist"] == "" class PathFormattingMixin: @@ -613,7 +611,7 @@ def _assert_dest(self, dest, i=None): i = self.i with _common.platform_posix(): actual = i.destination() - self.assertEqual(actual, dest) + assert actual == dest class DestinationFunctionTest(BeetsTestCase, PathFormattingMixin): @@ -911,7 +909,7 @@ def tearDown(self): def _assert_dest(self, dest): with _common.platform_posix(): the_dest = self.i.destination() - self.assertEqual(the_dest, b"/base/" + dest) + assert the_dest == b"/base/" + dest def test_undefined_value_not_substituted(self): self._assert_dest(b"the artist $foo") @@ -943,17 +941,17 @@ def setUp(self): def test_albuminfo_reflects_metadata(self): ai = self.lib.get_album(self.i) - self.assertEqual(ai.mb_albumartistid, self.i.mb_albumartistid) - self.assertEqual(ai.albumartist, self.i.albumartist) - self.assertEqual(ai.album, self.i.album) - self.assertEqual(ai.year, self.i.year) + assert ai.mb_albumartistid == self.i.mb_albumartistid + assert ai.albumartist == self.i.albumartist + assert ai.album == self.i.album + assert ai.year == self.i.year def test_albuminfo_stores_art(self): ai = self.lib.get_album(self.i) ai.artpath = "/my/great/art" ai.store() new_ai = self.lib.get_album(self.i) - self.assertEqual(new_ai.artpath, b"/my/great/art") + assert new_ai.artpath == b"/my/great/art" def test_albuminfo_for_two_items_doesnt_duplicate_row(self): i2 = item(self.lib) @@ -963,20 +961,20 @@ def test_albuminfo_for_two_items_doesnt_duplicate_row(self): c = self.lib._connection().cursor() c.execute("select * from albums where album=?", (self.i.album,)) # Cursor should only return one row. - self.assertIsNotNone(c.fetchone()) - self.assertIsNone(c.fetchone()) + assert c.fetchone() is not None + assert c.fetchone() is None def test_individual_tracks_have_no_albuminfo(self): i2 = item() i2.album = "aTotallyDifferentAlbum" self.lib.add(i2) ai = self.lib.get_album(i2) - self.assertIsNone(ai) + assert ai is None def test_get_album_by_id(self): ai = self.lib.get_album(self.i) ai = self.lib.get_album(self.i.id) - self.assertIsNotNone(ai) + assert ai is not None def test_album_items_consistent(self): ai = self.lib.get_album(self.i) @@ -991,29 +989,29 @@ def test_albuminfo_changes_affect_items(self): ai.album = "myNewAlbum" ai.store() i = self.lib.items()[0] - self.assertEqual(i.album, "myNewAlbum") + assert i.album == "myNewAlbum" def test_albuminfo_change_albumartist_changes_items(self): ai = self.lib.get_album(self.i) ai.albumartist = "myNewArtist" ai.store() i = self.lib.items()[0] - self.assertEqual(i.albumartist, "myNewArtist") - self.assertNotEqual(i.artist, "myNewArtist") + assert i.albumartist == "myNewArtist" + assert i.artist != "myNewArtist" def test_albuminfo_change_artist_does_change_items(self): ai = self.lib.get_album(self.i) ai.artist = "myNewArtist" ai.store(inherit=True) i = self.lib.items()[0] - self.assertEqual(i.artist, "myNewArtist") + assert i.artist == "myNewArtist" def test_albuminfo_change_artist_does_not_change_items(self): ai = self.lib.get_album(self.i) ai.artist = "myNewArtist" ai.store(inherit=False) i = self.lib.items()[0] - self.assertNotEqual(i.artist, "myNewArtist") + assert i.artist != "myNewArtist" def test_albuminfo_remove_removes_items(self): item_id = self.i.id @@ -1021,12 +1019,12 @@ def test_albuminfo_remove_removes_items(self): c = self.lib._connection().execute( "SELECT id FROM items WHERE id=?", (item_id,) ) - self.assertEqual(c.fetchone(), None) + assert c.fetchone() is None def test_removing_last_item_removes_album(self): - self.assertEqual(len(self.lib.albums()), 1) + assert len(self.lib.albums()) == 1 self.i.remove() - self.assertEqual(len(self.lib.albums()), 0) + assert len(self.lib.albums()) == 0 def test_noop_albuminfo_changes_affect_items(self): i = self.lib.items()[0] @@ -1036,7 +1034,7 @@ def test_noop_albuminfo_changes_affect_items(self): ai.album = ai.album ai.store() i = self.lib.items()[0] - self.assertEqual(i.album, ai.album) + assert i.album == ai.album class ArtDestinationTest(BeetsTestCase): @@ -1052,17 +1050,17 @@ def setUp(self): def test_art_filename_respects_setting(self): art = self.ai.art_destination("something.jpg") new_art = bytestring_path("%sartimage.jpg" % os.path.sep) - self.assertIn(new_art, art) + assert new_art in art def test_art_path_in_item_dir(self): art = self.ai.art_destination("something.jpg") track = self.i.destination() - self.assertEqual(os.path.dirname(art), os.path.dirname(track)) + assert os.path.dirname(art) == os.path.dirname(track) def test_art_path_sanitized(self): config["art_filename"] = "artXimage" art = self.ai.art_destination("something.jpg") - self.assertIn(b"artYimage", art) + assert b"artYimage" in art class PathStringTest(BeetsTestCase): @@ -1071,15 +1069,15 @@ def setUp(self): self.i = item(self.lib) def test_item_path_is_bytestring(self): - self.assertTrue(isinstance(self.i.path, bytes)) + assert isinstance(self.i.path, bytes) def test_fetched_item_path_is_bytestring(self): i = list(self.lib.items())[0] - self.assertTrue(isinstance(i.path, bytes)) + assert isinstance(i.path, bytes) def test_unicode_path_becomes_bytestring(self): self.i.path = "unicodepath" - self.assertTrue(isinstance(self.i.path, bytes)) + assert isinstance(self.i.path, bytes) def test_unicode_in_database_becomes_bytestring(self): self.lib._connection().execute( @@ -1089,14 +1087,14 @@ def test_unicode_in_database_becomes_bytestring(self): (self.i.id, "somepath"), ) i = list(self.lib.items())[0] - self.assertTrue(isinstance(i.path, bytes)) + assert isinstance(i.path, bytes) def test_special_chars_preserved_in_database(self): path = "b\xe1r".encode() self.i.path = path self.i.store() i = list(self.lib.items())[0] - self.assertEqual(i.path, path) + assert i.path == path def test_special_char_path_added_to_database(self): self.i.remove() @@ -1105,18 +1103,18 @@ def test_special_char_path_added_to_database(self): i.path = path self.lib.add(i) i = list(self.lib.items())[0] - self.assertEqual(i.path, path) + assert i.path == path def test_destination_returns_bytestring(self): self.i.artist = "b\xe1r" dest = self.i.destination() - self.assertTrue(isinstance(dest, bytes)) + assert isinstance(dest, bytes) def test_art_destination_returns_bytestring(self): self.i.artist = "b\xe1r" alb = self.lib.add_album([self.i]) dest = alb.art_destination("image.jpg") - self.assertTrue(isinstance(dest, bytes)) + assert isinstance(dest, bytes) def test_artpath_stores_special_chars(self): path = b"b\xe1r" @@ -1124,22 +1122,22 @@ def test_artpath_stores_special_chars(self): alb.artpath = path alb.store() alb = self.lib.get_album(self.i) - self.assertEqual(path, alb.artpath) + assert path == alb.artpath def test_sanitize_path_with_special_chars(self): path = "b\xe1r?" new_path = util.sanitize_path(path) - self.assertTrue(new_path.startswith("b\xe1r")) + assert new_path.startswith("b\xe1r") def test_sanitize_path_returns_unicode(self): path = "b\xe1r?" new_path = util.sanitize_path(path) - self.assertTrue(isinstance(new_path, str)) + assert isinstance(new_path, str) def test_unicode_artpath_becomes_bytestring(self): alb = self.lib.add_album([self.i]) alb.artpath = "somep\xe1th" - self.assertTrue(isinstance(alb.artpath, bytes)) + assert isinstance(alb.artpath, bytes) def test_unicode_artpath_in_database_decoded(self): alb = self.lib.add_album([self.i]) @@ -1147,7 +1145,7 @@ def test_unicode_artpath_in_database_decoded(self): "update albums set artpath=? where id=?", ("somep\xe1th", alb.id) ) alb = self.lib.get_album(alb.id) - self.assertTrue(isinstance(alb.artpath, bytes)) + assert isinstance(alb.artpath, bytes) class MtimeTest(BeetsTestCase): @@ -1170,63 +1168,63 @@ def _mtime(self): return int(os.path.getmtime(self.ipath)) def test_mtime_initially_up_to_date(self): - self.assertGreaterEqual(self.i.mtime, self._mtime()) + assert self.i.mtime >= self._mtime() def test_mtime_reset_on_db_modify(self): self.i.title = "something else" - self.assertLess(self.i.mtime, self._mtime()) + assert self.i.mtime < self._mtime() def test_mtime_up_to_date_after_write(self): self.i.title = "something else" self.i.write() - self.assertGreaterEqual(self.i.mtime, self._mtime()) + assert self.i.mtime >= self._mtime() def test_mtime_up_to_date_after_read(self): self.i.title = "something else" self.i.read() - self.assertGreaterEqual(self.i.mtime, self._mtime()) + assert self.i.mtime >= self._mtime() class ImportTimeTest(BeetsTestCase): def added(self): self.track = item() self.album = self.lib.add_album((self.track,)) - self.assertGreater(self.album.added, 0) - self.assertGreater(self.track.added, 0) + assert self.album.added > 0 + assert self.track.added > 0 def test_atime_for_singleton(self): self.singleton = item(self.lib) - self.assertGreater(self.singleton.added, 0) + assert self.singleton.added > 0 class TemplateTest(ItemInDBTestCase): def test_year_formatted_in_template(self): self.i.year = 123 self.i.store() - self.assertEqual(self.i.evaluate_template("$year"), "0123") + assert self.i.evaluate_template("$year") == "0123" def test_album_flexattr_appears_in_item_template(self): self.album = self.lib.add_album([self.i]) self.album.foo = "baz" self.album.store() - self.assertEqual(self.i.evaluate_template("$foo"), "baz") + assert self.i.evaluate_template("$foo") == "baz" def test_album_and_item_format(self): config["format_album"] = "foö $foo" album = beets.library.Album() album.foo = "bar" album.tagada = "togodo" - self.assertEqual(f"{album}", "foö bar") - self.assertEqual(f"{album:$tagada}", "togodo") - self.assertEqual(str(album), "foö bar") - self.assertEqual(bytes(album), b"fo\xc3\xb6 bar") + assert f"{album}" == "foö bar" + assert f"{album:$tagada}" == "togodo" + assert str(album) == "foö bar" + assert bytes(album) == b"fo\xc3\xb6 bar" config["format_item"] = "bar $foo" item = beets.library.Item() item.foo = "bar" item.tagada = "togodo" - self.assertEqual(f"{item}", "bar bar") - self.assertEqual(f"{item:$tagada}", "togodo") + assert f"{item}" == "bar bar" + assert f"{item:$tagada}" == "togodo" class UnicodePathTest(ItemInDBTestCase): @@ -1242,7 +1240,7 @@ class WriteTest(BeetsTestCase): def test_write_nonexistant(self): item = self.create_item() item.path = b"/path/does/not/exist" - with self.assertRaises(beets.library.ReadError): + with pytest.raises(beets.library.ReadError): item.write() def test_no_write_permission(self): @@ -1251,7 +1249,8 @@ def test_no_write_permission(self): os.chmod(path, stat.S_IRUSR) try: - self.assertRaises(beets.library.WriteError, item.write) + with pytest.raises(beets.library.WriteError): + item.write() finally: # Restore write permissions so the file can be cleaned up. @@ -1263,29 +1262,27 @@ def test_write_with_custom_path(self): shutil.copy(syspath(item.path), syspath(custom_path)) item["artist"] = "new artist" - self.assertNotEqual( - MediaFile(syspath(custom_path)).artist, "new artist" - ) - self.assertNotEqual(MediaFile(syspath(item.path)).artist, "new artist") + assert MediaFile(syspath(custom_path)).artist != "new artist" + assert MediaFile(syspath(item.path)).artist != "new artist" item.write(custom_path) - self.assertEqual(MediaFile(syspath(custom_path)).artist, "new artist") - self.assertNotEqual(MediaFile(syspath(item.path)).artist, "new artist") + assert MediaFile(syspath(custom_path)).artist == "new artist" + assert MediaFile(syspath(item.path)).artist != "new artist" def test_write_custom_tags(self): item = self.add_item_fixture(artist="old artist") item.write(tags={"artist": "new artist"}) - self.assertNotEqual(item.artist, "new artist") - self.assertEqual(MediaFile(syspath(item.path)).artist, "new artist") + assert item.artist != "new artist" + assert MediaFile(syspath(item.path)).artist == "new artist" def test_write_multi_tags(self): item = self.add_item_fixture(artist="old artist") item.write(tags={"artists": ["old artist", "another artist"]}) - self.assertEqual( - MediaFile(syspath(item.path)).artists, - ["old artist", "another artist"], - ) + assert MediaFile(syspath(item.path)).artists == [ + "old artist", + "another artist", + ] def test_write_multi_tags_id3v23(self): item = self.add_item_fixture(artist="old artist") @@ -1293,9 +1290,9 @@ def test_write_multi_tags_id3v23(self): tags={"artists": ["old artist", "another artist"]}, id3v23=True ) - self.assertEqual( - MediaFile(syspath(item.path)).artists, ["old artist/another artist"] - ) + assert MediaFile(syspath(item.path)).artists == [ + "old artist/another artist" + ] def test_write_date_field(self): # Since `date` is not a MediaField, this should do nothing. @@ -1303,41 +1300,40 @@ def test_write_date_field(self): clean_year = item.year item.date = "foo" item.write() - self.assertEqual(MediaFile(syspath(item.path)).year, clean_year) + assert MediaFile(syspath(item.path)).year == clean_year class ItemReadTest(unittest.TestCase): def test_unreadable_raise_read_error(self): unreadable = os.path.join(_common.RSRC, b"image-2x3.png") item = beets.library.Item() - with self.assertRaises(beets.library.ReadError) as cm: + with pytest.raises(beets.library.ReadError) as exc_info: item.read(unreadable) - self.assertIsInstance(cm.exception.reason, UnreadableFileError) + assert isinstance(exc_info.value.reason, UnreadableFileError) def test_nonexistent_raise_read_error(self): item = beets.library.Item() - with self.assertRaises(beets.library.ReadError): + with pytest.raises(beets.library.ReadError): item.read("/thisfiledoesnotexist") class FilesizeTest(BeetsTestCase): def test_filesize(self): item = self.add_item_fixture() - self.assertNotEqual(item.filesize, 0) + assert item.filesize != 0 def test_nonexistent_file(self): item = beets.library.Item() - self.assertEqual(item.filesize, 0) + assert item.filesize == 0 class ParseQueryTest(unittest.TestCase): def test_parse_invalid_query_string(self): - with self.assertRaises(beets.dbcore.InvalidQueryError) as raised: + with pytest.raises(beets.dbcore.query.ParsingError): beets.library.parse_query_string('foo"', None) - self.assertIsInstance(raised.exception, beets.dbcore.query.ParsingError) def test_parse_bytes(self): - with self.assertRaises(AssertionError): + with pytest.raises(AssertionError): beets.library.parse_query_string(b"query", None) @@ -1350,45 +1346,45 @@ def test_datetype(self): # format time_format = beets.config["time_format"].as_str() time_local = time.strftime(time_format, time.localtime(123456789)) - self.assertEqual(time_local, t.format(123456789)) + assert time_local == t.format(123456789) # parse - self.assertEqual(123456789.0, t.parse(time_local)) - self.assertEqual(123456789.0, t.parse("123456789.0")) - self.assertEqual(t.null, t.parse("not123456789.0")) - self.assertEqual(t.null, t.parse("1973-11-29")) + assert 123456789.0 == t.parse(time_local) + assert 123456789.0 == t.parse("123456789.0") + assert t.null == t.parse("not123456789.0") + assert t.null == t.parse("1973-11-29") def test_pathtype(self): t = beets.library.PathType() # format - self.assertEqual("/tmp", t.format("/tmp")) - self.assertEqual("/tmp/\xe4lbum", t.format("/tmp/\u00e4lbum")) + assert "/tmp" == t.format("/tmp") + assert "/tmp/\xe4lbum" == t.format("/tmp/\u00e4lbum") # parse - self.assertEqual(np(b"/tmp"), t.parse("/tmp")) - self.assertEqual(np(b"/tmp/\xc3\xa4lbum"), t.parse("/tmp/\u00e4lbum/")) + assert np(b"/tmp") == t.parse("/tmp") + assert np(b"/tmp/\xc3\xa4lbum") == t.parse("/tmp/\u00e4lbum/") def test_musicalkey(self): t = beets.library.MusicalKey() # parse - self.assertEqual("C#m", t.parse("c#m")) - self.assertEqual("Gm", t.parse("g minor")) - self.assertEqual("Not c#m", t.parse("not C#m")) + assert "C#m" == t.parse("c#m") + assert "Gm" == t.parse("g minor") + assert "Not c#m" == t.parse("not C#m") def test_durationtype(self): t = beets.library.DurationType() # format - self.assertEqual("1:01", t.format(61.23)) - self.assertEqual("60:01", t.format(3601.23)) - self.assertEqual("0:00", t.format(None)) + assert "1:01" == t.format(61.23) + assert "60:01" == t.format(3601.23) + assert "0:00" == t.format(None) # parse - self.assertEqual(61.0, t.parse("1:01")) - self.assertEqual(61.23, t.parse("61.23")) - self.assertEqual(3601.0, t.parse("60:01")) - self.assertEqual(t.null, t.parse("1:00:01")) - self.assertEqual(t.null, t.parse("not61.23")) + assert 61.0 == t.parse("1:01") + assert 61.23 == t.parse("61.23") + assert 3601.0 == t.parse("60:01") + assert t.null == t.parse("1:00:01") + assert t.null == t.parse("not61.23") # config format_raw_length beets.config["format_raw_length"] = True - self.assertEqual(61.23, t.format(61.23)) - self.assertEqual(3601.23, t.format(3601.23)) + assert 61.23 == t.format(61.23) + assert 3601.23 == t.format(3601.23) diff --git a/test/test_logging.py b/test/test_logging.py index 30d79f57e0..0aa0d85d3c 100644 --- a/test/test_logging.py +++ b/test/test_logging.py @@ -21,22 +21,22 @@ class LoggingTest(BeetsTestCase): def test_logging_management(self): l1 = log.getLogger("foo123") l2 = blog.getLogger("foo123") - self.assertEqual(l1, l2) - self.assertEqual(l1.__class__, log.Logger) + assert l1 == l2 + assert l1.__class__ == log.Logger l3 = blog.getLogger("bar123") l4 = log.getLogger("bar123") - self.assertEqual(l3, l4) - self.assertEqual(l3.__class__, blog.BeetsLogger) - self.assertIsInstance( + assert l3 == l4 + assert l3.__class__ == blog.BeetsLogger + assert isinstance( l3, (blog.StrFormatLogger, blog.ThreadLocalLevelLogger) ) l5 = l3.getChild("shalala") - self.assertEqual(l5.__class__, blog.BeetsLogger) + assert l5.__class__ == blog.BeetsLogger l6 = blog.getLogger() - self.assertNotEqual(l1, l6) + assert l1 != l6 def test_str_format_logging(self): l = blog.getLogger("baz123") @@ -48,7 +48,7 @@ def test_str_format_logging(self): l.warning("foo {0} {bar}", "oof", bar="baz") handler.flush() - self.assertTrue(stream.getvalue(), "foo oof baz") + assert stream.getvalue(), "foo oof baz" class LoggingLevelTest(AsIsImporterMixin, PluginMixin, ImportTestCase): @@ -86,73 +86,73 @@ def test_command_level0(self): self.config["verbose"] = 0 with helper.capture_log() as logs: self.run_command("dummy") - self.assertIn("dummy: warning cmd", logs) - self.assertIn("dummy: info cmd", logs) - self.assertNotIn("dummy: debug cmd", logs) + assert "dummy: warning cmd" in logs + assert "dummy: info cmd" in logs + assert "dummy: debug cmd" not in logs def test_command_level1(self): self.config["verbose"] = 1 with helper.capture_log() as logs: self.run_command("dummy") - self.assertIn("dummy: warning cmd", logs) - self.assertIn("dummy: info cmd", logs) - self.assertIn("dummy: debug cmd", logs) + assert "dummy: warning cmd" in logs + assert "dummy: info cmd" in logs + assert "dummy: debug cmd" in logs def test_command_level2(self): self.config["verbose"] = 2 with helper.capture_log() as logs: self.run_command("dummy") - self.assertIn("dummy: warning cmd", logs) - self.assertIn("dummy: info cmd", logs) - self.assertIn("dummy: debug cmd", logs) + assert "dummy: warning cmd" in logs + assert "dummy: info cmd" in logs + assert "dummy: debug cmd" in logs def test_listener_level0(self): self.config["verbose"] = 0 with helper.capture_log() as logs: plugins.send("dummy_event") - self.assertIn("dummy: warning listener", logs) - self.assertNotIn("dummy: info listener", logs) - self.assertNotIn("dummy: debug listener", logs) + assert "dummy: warning listener" in logs + assert "dummy: info listener" not in logs + assert "dummy: debug listener" not in logs def test_listener_level1(self): self.config["verbose"] = 1 with helper.capture_log() as logs: plugins.send("dummy_event") - self.assertIn("dummy: warning listener", logs) - self.assertIn("dummy: info listener", logs) - self.assertNotIn("dummy: debug listener", logs) + assert "dummy: warning listener" in logs + assert "dummy: info listener" in logs + assert "dummy: debug listener" not in logs def test_listener_level2(self): self.config["verbose"] = 2 with helper.capture_log() as logs: plugins.send("dummy_event") - self.assertIn("dummy: warning listener", logs) - self.assertIn("dummy: info listener", logs) - self.assertIn("dummy: debug listener", logs) + assert "dummy: warning listener" in logs + assert "dummy: info listener" in logs + assert "dummy: debug listener" in logs def test_import_stage_level0(self): self.config["verbose"] = 0 with helper.capture_log() as logs: 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) + assert "dummy: warning import_stage" in logs + assert "dummy: info import_stage" not in logs + assert "dummy: debug import_stage" not in logs def test_import_stage_level1(self): self.config["verbose"] = 1 with helper.capture_log() as logs: 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) + assert "dummy: warning import_stage" in logs + assert "dummy: info import_stage" in logs + assert "dummy: debug import_stage" not in logs def test_import_stage_level2(self): self.config["verbose"] = 2 with helper.capture_log() as logs: 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) + assert "dummy: warning import_stage" in logs + assert "dummy: info import_stage" in logs + assert "dummy: debug import_stage" in logs @_common.slow_test() @@ -182,20 +182,20 @@ def log_all(self, name): def listener1(self): try: - self.test_case.assertEqual(self._log.level, log.INFO) + assert self._log.level == log.INFO self.t1_step = 1 self.lock1.acquire() - self.test_case.assertEqual(self._log.level, log.INFO) + assert self._log.level == log.INFO self.t1_step = 2 except Exception as e: self.exc = e def listener2(self): try: - self.test_case.assertEqual(self._log.level, log.DEBUG) + assert self._log.level == log.DEBUG self.t2_step = 1 self.lock2.acquire() - self.test_case.assertEqual(self._log.level, log.DEBUG) + assert self._log.level == log.DEBUG self.t2_step = 2 except Exception as e: self.exc = e @@ -210,37 +210,37 @@ def check_dp_exc(): try: dp.lock1.acquire() dp.lock2.acquire() - self.assertEqual(dp._log.level, log.NOTSET) + assert dp._log.level == log.NOTSET self.config["verbose"] = 1 t1 = threading.Thread(target=dp.listeners["dummy_event1"][0]) t1.start() # blocked. t1 tested its log level while dp.t1_step != 1: check_dp_exc() - self.assertTrue(t1.is_alive()) - self.assertEqual(dp._log.level, log.NOTSET) + assert t1.is_alive() + assert dp._log.level == log.NOTSET self.config["verbose"] = 2 t2 = threading.Thread(target=dp.listeners["dummy_event2"][0]) t2.start() # blocked. t2 tested its log level while dp.t2_step != 1: check_dp_exc() - self.assertTrue(t2.is_alive()) - self.assertEqual(dp._log.level, log.NOTSET) + assert t2.is_alive() + assert dp._log.level == log.NOTSET dp.lock1.release() # dummy_event1 tests its log level + finishes while dp.t1_step != 2: check_dp_exc() t1.join(0.1) - self.assertFalse(t1.is_alive()) - self.assertTrue(t2.is_alive()) - self.assertEqual(dp._log.level, log.NOTSET) + assert not t1.is_alive() + assert t2.is_alive() + assert dp._log.level == log.NOTSET dp.lock2.release() # dummy_event2 tests its log level + finishes while dp.t2_step != 2: check_dp_exc() t2.join(0.1) - self.assertFalse(t2.is_alive()) + assert not t2.is_alive() except Exception: print("Alive threads:", threading.enumerate()) @@ -260,16 +260,16 @@ def test_root_logger_levels(self): blog.getLogger("beets").set_global_level(blog.WARNING) with helper.capture_log() as logs: self.run_asis_importer() - self.assertEqual(logs, []) + assert logs == [] blog.getLogger("beets").set_global_level(blog.INFO) with helper.capture_log() as logs: self.run_asis_importer() for l in logs: - self.assertIn("import", l) - self.assertIn("album", l) + assert "import" in l + assert "album" in l blog.getLogger("beets").set_global_level(blog.DEBUG) with helper.capture_log() as logs: self.run_asis_importer() - self.assertIn("Sending event: database_change", logs) + assert "Sending event: database_change" in logs diff --git a/test/test_m3ufile.py b/test/test_m3ufile.py index 22a4105bca..e9fbee644f 100644 --- a/test/test_m3ufile.py +++ b/test/test_m3ufile.py @@ -20,6 +20,8 @@ from shutil import rmtree from tempfile import mkdtemp +import pytest + from beets.test._common import RSRC from beets.util import bytestring_path from beets.util.m3u import EmptyPlaylistError, M3UFile @@ -33,7 +35,7 @@ def test_playlist_write_empty(self): tempdir = bytestring_path(mkdtemp()) the_playlist_file = path.join(tempdir, b"playlist.m3u8") m3ufile = M3UFile(the_playlist_file) - with self.assertRaises(EmptyPlaylistError): + with pytest.raises(EmptyPlaylistError): m3ufile.write() rmtree(tempdir) @@ -49,7 +51,7 @@ def test_playlist_write(self): ] ) m3ufile.write() - self.assertTrue(path.exists(the_playlist_file)) + assert path.exists(the_playlist_file) rmtree(tempdir) def test_playlist_write_unicode(self): @@ -64,7 +66,7 @@ def test_playlist_write_unicode(self): ] ) m3ufile.write() - self.assertTrue(path.exists(the_playlist_file)) + assert path.exists(the_playlist_file) rmtree(tempdir) @unittest.skipUnless(sys.platform == "win32", "win32") @@ -82,23 +84,16 @@ def test_playlist_write_and_read_unicode_windows(self): ] ) m3ufile.write() - self.assertTrue(path.exists(the_playlist_file)) + assert path.exists(the_playlist_file) m3ufile_read = M3UFile(the_playlist_file) m3ufile_read.load() - self.assertEqual( - m3ufile.media_list[0], - bytestring_path( - path.join("x:\\", "This", "is", "å", "path", "to_a_file.mp3") - ), + assert m3ufile.media_list[0] == bytestring_path( + path.join("x:\\", "This", "is", "å", "path", "to_a_file.mp3") ) - self.assertEqual( - m3ufile.media_list[1], - bytestring_path(r"x:\This\is\another\path\tö_a_file.mp3"), - bytestring_path( - path.join( - "x:\\", "This", "is", "another", "path", "tö_a_file.mp3" - ) - ), + assert m3ufile.media_list[1] == bytestring_path( + r"x:\This\is\another\path\tö_a_file.mp3" + ), bytestring_path( + path.join("x:\\", "This", "is", "another", "path", "tö_a_file.mp3") ) rmtree(tempdir) @@ -108,9 +103,8 @@ def test_playlist_load_ascii(self): the_playlist_file = path.join(RSRC, b"playlist.m3u") m3ufile = M3UFile(the_playlist_file) m3ufile.load() - self.assertEqual( - m3ufile.media_list[0], - bytestring_path("/This/is/a/path/to_a_file.mp3"), + assert m3ufile.media_list[0] == bytestring_path( + "/This/is/a/path/to_a_file.mp3" ) @unittest.skipIf(sys.platform == "win32", "win32") @@ -119,9 +113,8 @@ def test_playlist_load_unicode(self): the_playlist_file = path.join(RSRC, b"playlist.m3u8") m3ufile = M3UFile(the_playlist_file) m3ufile.load() - self.assertEqual( - m3ufile.media_list[0], - bytestring_path("/This/is/å/path/to_a_file.mp3"), + assert m3ufile.media_list[0] == bytestring_path( + "/This/is/å/path/to_a_file.mp3" ) @unittest.skipUnless(sys.platform == "win32", "win32") @@ -133,18 +126,18 @@ def test_playlist_load_unicode_windows(self): ) m3ufile = M3UFile(the_playlist_file) m3ufile.load() - self.assertEqual(m3ufile.media_list[0], winpath) + assert m3ufile.media_list[0] == winpath def test_playlist_load_extm3u(self): """Test loading a playlist with an #EXTM3U header.""" the_playlist_file = path.join(RSRC, b"playlist.m3u") m3ufile = M3UFile(the_playlist_file) m3ufile.load() - self.assertTrue(m3ufile.extm3u) + assert m3ufile.extm3u def test_playlist_load_non_extm3u(self): """Test loading a playlist without an #EXTM3U header.""" the_playlist_file = path.join(RSRC, b"playlist_non_ext.m3u") m3ufile = M3UFile(the_playlist_file) m3ufile.load() - self.assertFalse(m3ufile.extm3u) + assert not m3ufile.extm3u diff --git a/test/test_mb.py b/test/test_mb.py index 4b7d2806a2..37b5c0fff4 100644 --- a/test/test_mb.py +++ b/test/test_mb.py @@ -12,10 +12,8 @@ # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. -"""Tests for MusicBrainz API wrapper. -""" +"""Tests for MusicBrainz API wrapper.""" -import unittest from unittest import mock from beets import config @@ -213,25 +211,25 @@ def _make_track( def test_parse_release_with_year(self): release = self._make_release("1984") d = mb.album_info(release) - self.assertEqual(d.album, "ALBUM TITLE") - self.assertEqual(d.album_id, "ALBUM ID") - self.assertEqual(d.artist, "ARTIST NAME") - self.assertEqual(d.artist_id, "ARTIST ID") - self.assertEqual(d.original_year, 1984) - self.assertEqual(d.year, 3001) - self.assertEqual(d.artist_credit, "ARTIST CREDIT") + assert d.album == "ALBUM TITLE" + assert d.album_id == "ALBUM ID" + assert d.artist == "ARTIST NAME" + assert d.artist_id == "ARTIST ID" + assert d.original_year == 1984 + assert d.year == 3001 + assert d.artist_credit == "ARTIST CREDIT" def test_parse_release_type(self): release = self._make_release("1984") d = mb.album_info(release) - self.assertEqual(d.albumtype, "album") + assert d.albumtype == "album" def test_parse_release_full_date(self): release = self._make_release("1987-03-31") d = mb.album_info(release) - self.assertEqual(d.original_year, 1987) - self.assertEqual(d.original_month, 3) - self.assertEqual(d.original_day, 31) + assert d.original_year == 1987 + assert d.original_month == 3 + assert d.original_day == 31 def test_parse_tracks(self): tracks = [ @@ -242,13 +240,13 @@ def test_parse_tracks(self): d = mb.album_info(release) t = d.tracks - self.assertEqual(len(t), 2) - self.assertEqual(t[0].title, "TITLE ONE") - self.assertEqual(t[0].track_id, "ID ONE") - self.assertEqual(t[0].length, 100.0) - self.assertEqual(t[1].title, "TITLE TWO") - self.assertEqual(t[1].track_id, "ID TWO") - self.assertEqual(t[1].length, 200.0) + assert len(t) == 2 + assert t[0].title == "TITLE ONE" + assert t[0].track_id == "ID ONE" + assert t[0].length == 100.0 + assert t[1].title == "TITLE TWO" + assert t[1].track_id == "ID TWO" + assert t[1].length == 200.0 def test_parse_track_indices(self): tracks = [ @@ -259,10 +257,10 @@ def test_parse_track_indices(self): d = mb.album_info(release) t = d.tracks - self.assertEqual(t[0].medium_index, 1) - self.assertEqual(t[0].index, 1) - self.assertEqual(t[1].medium_index, 2) - self.assertEqual(t[1].index, 2) + assert t[0].medium_index == 1 + assert t[0].index == 1 + assert t[1].medium_index == 2 + assert t[1].index == 2 def test_parse_medium_numbers_single_medium(self): tracks = [ @@ -272,10 +270,10 @@ def test_parse_medium_numbers_single_medium(self): release = self._make_release(tracks=tracks) d = mb.album_info(release) - self.assertEqual(d.mediums, 1) + assert d.mediums == 1 t = d.tracks - self.assertEqual(t[0].medium, 1) - self.assertEqual(t[1].medium, 1) + assert t[0].medium == 1 + assert t[1].medium == 1 def test_parse_medium_numbers_two_mediums(self): tracks = [ @@ -299,91 +297,91 @@ def test_parse_medium_numbers_two_mediums(self): ) d = mb.album_info(release) - self.assertEqual(d.mediums, 2) + assert d.mediums == 2 t = d.tracks - self.assertEqual(t[0].medium, 1) - self.assertEqual(t[0].medium_index, 1) - self.assertEqual(t[0].index, 1) - self.assertEqual(t[1].medium, 2) - self.assertEqual(t[1].medium_index, 1) - self.assertEqual(t[1].index, 2) + assert t[0].medium == 1 + assert t[0].medium_index == 1 + assert t[0].index == 1 + assert t[1].medium == 2 + assert t[1].medium_index == 1 + assert t[1].index == 2 def test_parse_release_year_month_only(self): release = self._make_release("1987-03") d = mb.album_info(release) - self.assertEqual(d.original_year, 1987) - self.assertEqual(d.original_month, 3) + assert d.original_year == 1987 + assert d.original_month == 3 def test_no_durations(self): tracks = [self._make_track("TITLE", "ID", None)] release = self._make_release(tracks=tracks) d = mb.album_info(release) - self.assertIsNone(d.tracks[0].length) + assert d.tracks[0].length is None def test_track_length_overrides_recording_length(self): tracks = [self._make_track("TITLE", "ID", 1.0 * 1000.0)] release = self._make_release(tracks=tracks, track_length=2.0 * 1000.0) d = mb.album_info(release) - self.assertEqual(d.tracks[0].length, 2.0) + assert d.tracks[0].length == 2.0 def test_no_release_date(self): release = self._make_release(None) d = mb.album_info(release) - self.assertFalse(d.original_year) - self.assertFalse(d.original_month) - self.assertFalse(d.original_day) + assert not d.original_year + assert not d.original_month + assert not d.original_day def test_various_artists_defaults_false(self): release = self._make_release(None) d = mb.album_info(release) - self.assertFalse(d.va) + assert not d.va def test_detect_various_artists(self): release = self._make_release(None) release["artist-credit"][0]["artist"]["id"] = mb.VARIOUS_ARTISTS_ID d = mb.album_info(release) - self.assertTrue(d.va) + assert d.va def test_parse_artist_sort_name(self): release = self._make_release(None) d = mb.album_info(release) - self.assertEqual(d.artist_sort, "ARTIST SORT NAME") + assert d.artist_sort == "ARTIST SORT NAME" def test_parse_releasegroupid(self): release = self._make_release(None) d = mb.album_info(release) - self.assertEqual(d.releasegroup_id, "RELEASE GROUP ID") + assert d.releasegroup_id == "RELEASE GROUP ID" def test_parse_asin(self): release = self._make_release(None) d = mb.album_info(release) - self.assertEqual(d.asin, "ALBUM ASIN") + assert d.asin == "ALBUM ASIN" def test_parse_catalognum(self): release = self._make_release(None) d = mb.album_info(release) - self.assertEqual(d.catalognum, "CATALOG NUMBER") + assert d.catalognum == "CATALOG NUMBER" def test_parse_textrepr(self): release = self._make_release(None) d = mb.album_info(release) - self.assertEqual(d.script, "SCRIPT") - self.assertEqual(d.language, "LANGUAGE") + assert d.script == "SCRIPT" + assert d.language == "LANGUAGE" def test_parse_country(self): release = self._make_release(None) d = mb.album_info(release) - self.assertEqual(d.country, "COUNTRY") + assert d.country == "COUNTRY" def test_parse_status(self): release = self._make_release(None) d = mb.album_info(release) - self.assertEqual(d.albumstatus, "STATUS") + assert d.albumstatus == "STATUS" def test_parse_barcode(self): release = self._make_release(None) d = mb.album_info(release) - self.assertEqual(d.barcode, "BARCODE") + assert d.barcode == "BARCODE" def test_parse_media(self): tracks = [ @@ -392,13 +390,13 @@ def test_parse_media(self): ] release = self._make_release(None, tracks=tracks) d = mb.album_info(release) - self.assertEqual(d.media, "FORMAT") + assert d.media == "FORMAT" def test_parse_disambig(self): release = self._make_release(None) d = mb.album_info(release) - self.assertEqual(d.albumdisambig, "R_DISAMBIGUATION") - self.assertEqual(d.releasegroupdisambig, "RG_DISAMBIGUATION") + assert d.albumdisambig == "R_DISAMBIGUATION" + assert d.releasegroupdisambig == "RG_DISAMBIGUATION" def test_parse_disctitle(self): tracks = [ @@ -408,64 +406,64 @@ def test_parse_disctitle(self): release = self._make_release(None, tracks=tracks) d = mb.album_info(release) t = d.tracks - self.assertEqual(t[0].disctitle, "MEDIUM TITLE") - self.assertEqual(t[1].disctitle, "MEDIUM TITLE") + assert t[0].disctitle == "MEDIUM TITLE" + assert t[1].disctitle == "MEDIUM TITLE" def test_missing_language(self): release = self._make_release(None) del release["text-representation"]["language"] d = mb.album_info(release) - self.assertIsNone(d.language) + assert d.language is None def test_parse_recording_artist(self): tracks = [self._make_track("a", "b", 1, True)] release = self._make_release(None, tracks=tracks) track = mb.album_info(release).tracks[0] - self.assertEqual(track.artist, "RECORDING ARTIST NAME") - self.assertEqual(track.artist_id, "RECORDING ARTIST ID") - self.assertEqual(track.artist_sort, "RECORDING ARTIST SORT NAME") - self.assertEqual(track.artist_credit, "RECORDING ARTIST CREDIT") + assert track.artist == "RECORDING ARTIST NAME" + assert track.artist_id == "RECORDING ARTIST ID" + assert track.artist_sort == "RECORDING ARTIST SORT NAME" + assert track.artist_credit == "RECORDING ARTIST CREDIT" def test_parse_recording_artist_multi(self): tracks = [self._make_track("a", "b", 1, True, multi_artist_credit=True)] release = self._make_release(None, tracks=tracks) track = mb.album_info(release).tracks[0] - self.assertEqual( - track.artist, "RECORDING ARTIST NAME & RECORDING ARTIST 2 NAME" + assert track.artist == "RECORDING ARTIST NAME & RECORDING ARTIST 2 NAME" + assert track.artist_id == "RECORDING ARTIST ID" + assert ( + track.artist_sort + == "RECORDING ARTIST SORT NAME & RECORDING ARTIST 2 SORT NAME" ) - self.assertEqual(track.artist_id, "RECORDING ARTIST ID") - self.assertEqual( - track.artist_sort, - "RECORDING ARTIST SORT NAME & RECORDING ARTIST 2 SORT NAME", - ) - self.assertEqual( - track.artist_credit, - "RECORDING ARTIST CREDIT & RECORDING ARTIST 2 CREDIT", + assert ( + track.artist_credit + == "RECORDING ARTIST CREDIT & RECORDING ARTIST 2 CREDIT" ) - self.assertEqual( - track.artists, ["RECORDING ARTIST NAME", "RECORDING ARTIST 2 NAME"] - ) - self.assertEqual( - track.artists_ids, ["RECORDING ARTIST ID", "RECORDING ARTIST 2 ID"] - ) - self.assertEqual( - track.artists_sort, - ["RECORDING ARTIST SORT NAME", "RECORDING ARTIST 2 SORT NAME"], - ) - self.assertEqual( - track.artists_credit, - ["RECORDING ARTIST CREDIT", "RECORDING ARTIST 2 CREDIT"], - ) + assert track.artists == [ + "RECORDING ARTIST NAME", + "RECORDING ARTIST 2 NAME", + ] + assert track.artists_ids == [ + "RECORDING ARTIST ID", + "RECORDING ARTIST 2 ID", + ] + assert track.artists_sort == [ + "RECORDING ARTIST SORT NAME", + "RECORDING ARTIST 2 SORT NAME", + ] + assert track.artists_credit == [ + "RECORDING ARTIST CREDIT", + "RECORDING ARTIST 2 CREDIT", + ] def test_track_artist_overrides_recording_artist(self): tracks = [self._make_track("a", "b", 1, True)] release = self._make_release(None, tracks=tracks, track_artist=True) track = mb.album_info(release).tracks[0] - self.assertEqual(track.artist, "TRACK ARTIST NAME") - self.assertEqual(track.artist_id, "TRACK ARTIST ID") - self.assertEqual(track.artist_sort, "TRACK ARTIST SORT NAME") - self.assertEqual(track.artist_credit, "TRACK ARTIST CREDIT") + assert track.artist == "TRACK ARTIST NAME" + assert track.artist_id == "TRACK ARTIST ID" + assert track.artist_sort == "TRACK ARTIST SORT NAME" + assert track.artist_credit == "TRACK ARTIST CREDIT" def test_track_artist_overrides_recording_artist_multi(self): tracks = [self._make_track("a", "b", 1, True, multi_artist_credit=True)] @@ -473,43 +471,37 @@ def test_track_artist_overrides_recording_artist_multi(self): None, tracks=tracks, track_artist=True, multi_artist_credit=True ) track = mb.album_info(release).tracks[0] - self.assertEqual( - track.artist, "TRACK ARTIST NAME & TRACK ARTIST 2 NAME" - ) - self.assertEqual(track.artist_id, "TRACK ARTIST ID") - self.assertEqual( - track.artist_sort, - "TRACK ARTIST SORT NAME & TRACK ARTIST 2 SORT NAME", + assert track.artist == "TRACK ARTIST NAME & TRACK ARTIST 2 NAME" + assert track.artist_id == "TRACK ARTIST ID" + assert ( + track.artist_sort + == "TRACK ARTIST SORT NAME & TRACK ARTIST 2 SORT NAME" ) - self.assertEqual( - track.artist_credit, "TRACK ARTIST CREDIT & TRACK ARTIST 2 CREDIT" + assert ( + track.artist_credit == "TRACK ARTIST CREDIT & TRACK ARTIST 2 CREDIT" ) - self.assertEqual( - track.artists, ["TRACK ARTIST NAME", "TRACK ARTIST 2 NAME"] - ) - self.assertEqual( - track.artists_ids, ["TRACK ARTIST ID", "TRACK ARTIST 2 ID"] - ) - self.assertEqual( - track.artists_sort, - ["TRACK ARTIST SORT NAME", "TRACK ARTIST 2 SORT NAME"], - ) - self.assertEqual( - track.artists_credit, - ["TRACK ARTIST CREDIT", "TRACK ARTIST 2 CREDIT"], - ) + assert track.artists == ["TRACK ARTIST NAME", "TRACK ARTIST 2 NAME"] + assert track.artists_ids == ["TRACK ARTIST ID", "TRACK ARTIST 2 ID"] + assert track.artists_sort == [ + "TRACK ARTIST SORT NAME", + "TRACK ARTIST 2 SORT NAME", + ] + assert track.artists_credit == [ + "TRACK ARTIST CREDIT", + "TRACK ARTIST 2 CREDIT", + ] def test_parse_recording_remixer(self): tracks = [self._make_track("a", "b", 1, remixer=True)] release = self._make_release(None, tracks=tracks) track = mb.album_info(release).tracks[0] - self.assertEqual(track.remixer, "RECORDING REMIXER ARTIST NAME") + assert track.remixer == "RECORDING REMIXER ARTIST NAME" def test_data_source(self): release = self._make_release() d = mb.album_info(release) - self.assertEqual(d.data_source, "MusicBrainz") + assert d.data_source == "MusicBrainz" def test_ignored_media(self): config["match"]["ignored_media"] = ["IGNORED1", "IGNORED2"] @@ -519,7 +511,7 @@ def test_ignored_media(self): ] release = self._make_release(tracks=tracks, medium_format="IGNORED1") d = mb.album_info(release) - self.assertEqual(len(d.tracks), 0) + assert len(d.tracks) == 0 def test_no_ignored_media(self): config["match"]["ignored_media"] = ["IGNORED1", "IGNORED2"] @@ -529,7 +521,7 @@ def test_no_ignored_media(self): ] release = self._make_release(tracks=tracks, medium_format="NON-IGNORED") d = mb.album_info(release) - self.assertEqual(len(d.tracks), 2) + assert len(d.tracks) == 2 def test_skip_data_track(self): tracks = [ @@ -539,9 +531,9 @@ def test_skip_data_track(self): ] release = self._make_release(tracks=tracks) d = mb.album_info(release) - self.assertEqual(len(d.tracks), 2) - self.assertEqual(d.tracks[0].title, "TITLE ONE") - self.assertEqual(d.tracks[1].title, "TITLE TWO") + assert len(d.tracks) == 2 + assert d.tracks[0].title == "TITLE ONE" + assert d.tracks[1].title == "TITLE TWO" def test_skip_audio_data_tracks_by_default(self): tracks = [ @@ -555,9 +547,9 @@ def test_skip_audio_data_tracks_by_default(self): ] release = self._make_release(tracks=tracks, data_tracks=data_tracks) d = mb.album_info(release) - self.assertEqual(len(d.tracks), 2) - self.assertEqual(d.tracks[0].title, "TITLE ONE") - self.assertEqual(d.tracks[1].title, "TITLE TWO") + assert len(d.tracks) == 2 + assert d.tracks[0].title == "TITLE ONE" + assert d.tracks[1].title == "TITLE TWO" def test_no_skip_audio_data_tracks_if_configured(self): config["match"]["ignore_data_tracks"] = False @@ -572,10 +564,10 @@ def test_no_skip_audio_data_tracks_if_configured(self): ] release = self._make_release(tracks=tracks, data_tracks=data_tracks) d = mb.album_info(release) - self.assertEqual(len(d.tracks), 3) - self.assertEqual(d.tracks[0].title, "TITLE ONE") - self.assertEqual(d.tracks[1].title, "TITLE TWO") - self.assertEqual(d.tracks[2].title, "TITLE AUDIO DATA") + assert len(d.tracks) == 3 + assert d.tracks[0].title == "TITLE ONE" + assert d.tracks[1].title == "TITLE TWO" + assert d.tracks[2].title == "TITLE AUDIO DATA" def test_skip_video_tracks_by_default(self): tracks = [ @@ -587,9 +579,9 @@ def test_skip_video_tracks_by_default(self): ] release = self._make_release(tracks=tracks) d = mb.album_info(release) - self.assertEqual(len(d.tracks), 2) - self.assertEqual(d.tracks[0].title, "TITLE ONE") - self.assertEqual(d.tracks[1].title, "TITLE TWO") + assert len(d.tracks) == 2 + assert d.tracks[0].title == "TITLE ONE" + assert d.tracks[1].title == "TITLE TWO" def test_skip_video_data_tracks_by_default(self): tracks = [ @@ -603,9 +595,9 @@ def test_skip_video_data_tracks_by_default(self): ] release = self._make_release(tracks=tracks, data_tracks=data_tracks) d = mb.album_info(release) - self.assertEqual(len(d.tracks), 2) - self.assertEqual(d.tracks[0].title, "TITLE ONE") - self.assertEqual(d.tracks[1].title, "TITLE TWO") + assert len(d.tracks) == 2 + assert d.tracks[0].title == "TITLE ONE" + assert d.tracks[1].title == "TITLE TWO" def test_no_skip_video_tracks_if_configured(self): config["match"]["ignore_data_tracks"] = False @@ -619,10 +611,10 @@ def test_no_skip_video_tracks_if_configured(self): ] release = self._make_release(tracks=tracks) d = mb.album_info(release) - self.assertEqual(len(d.tracks), 3) - self.assertEqual(d.tracks[0].title, "TITLE ONE") - self.assertEqual(d.tracks[1].title, "TITLE VIDEO") - self.assertEqual(d.tracks[2].title, "TITLE TWO") + assert len(d.tracks) == 3 + assert d.tracks[0].title == "TITLE ONE" + assert d.tracks[1].title == "TITLE VIDEO" + assert d.tracks[2].title == "TITLE TWO" def test_no_skip_video_data_tracks_if_configured(self): config["match"]["ignore_data_tracks"] = False @@ -638,10 +630,10 @@ def test_no_skip_video_data_tracks_if_configured(self): ] release = self._make_release(tracks=tracks, data_tracks=data_tracks) d = mb.album_info(release) - self.assertEqual(len(d.tracks), 3) - self.assertEqual(d.tracks[0].title, "TITLE ONE") - self.assertEqual(d.tracks[1].title, "TITLE TWO") - self.assertEqual(d.tracks[2].title, "TITLE VIDEO") + assert len(d.tracks) == 3 + assert d.tracks[0].title == "TITLE ONE" + assert d.tracks[1].title == "TITLE TWO" + assert d.tracks[2].title == "TITLE VIDEO" def test_track_disambiguation(self): tracks = [ @@ -657,27 +649,27 @@ def test_track_disambiguation(self): d = mb.album_info(release) t = d.tracks - self.assertEqual(len(t), 2) - self.assertIsNone(t[0].trackdisambig) - self.assertEqual(t[1].trackdisambig, "SECOND TRACK") + assert len(t) == 2 + assert t[0].trackdisambig is None + assert t[1].trackdisambig == "SECOND TRACK" class ParseIDTest(BeetsTestCase): def test_parse_id_correct(self): id_string = "28e32c71-1450-463e-92bf-e0a46446fc11" out = mb._parse_id(id_string) - self.assertEqual(out, id_string) + assert out == id_string def test_parse_id_non_id_returns_none(self): id_string = "blah blah" out = mb._parse_id(id_string) - self.assertIsNone(out) + assert out is None def test_parse_id_url_finds_id(self): id_string = "28e32c71-1450-463e-92bf-e0a46446fc11" id_url = "https://musicbrainz.org/entity/%s" % id_string out = mb._parse_id(id_url) - self.assertEqual(out, id_string) + assert out == id_string class ArtistFlatteningTest(BeetsTestCase): @@ -705,26 +697,26 @@ def _add_alias(self, credit_dict, suffix="", locale="", primary=False): def test_single_artist(self): credit = [self._credit_dict()] a, s, c = mb._flatten_artist_credit(credit) - self.assertEqual(a, "NAME") - self.assertEqual(s, "SORT") - self.assertEqual(c, "CREDIT") + assert a == "NAME" + assert s == "SORT" + assert c == "CREDIT" a, s, c = mb._multi_artist_credit(credit, include_join_phrase=False) - self.assertEqual(a, ["NAME"]) - self.assertEqual(s, ["SORT"]) - self.assertEqual(c, ["CREDIT"]) + assert a == ["NAME"] + assert s == ["SORT"] + assert c == ["CREDIT"] def test_two_artists(self): credit = [self._credit_dict("a"), " AND ", self._credit_dict("b")] a, s, c = mb._flatten_artist_credit(credit) - self.assertEqual(a, "NAMEa AND NAMEb") - self.assertEqual(s, "SORTa AND SORTb") - self.assertEqual(c, "CREDITa AND CREDITb") + assert a == "NAMEa AND NAMEb" + assert s == "SORTa AND SORTb" + assert c == "CREDITa AND CREDITb" a, s, c = mb._multi_artist_credit(credit, include_join_phrase=False) - self.assertEqual(a, ["NAMEa", "NAMEb"]) - self.assertEqual(s, ["SORTa", "SORTb"]) - self.assertEqual(c, ["CREDITa", "CREDITb"]) + assert a == ["NAMEa", "NAMEb"] + assert s == ["SORTa", "SORTb"] + assert c == ["CREDITa", "CREDITb"] def test_alias(self): credit_dict = self._credit_dict() @@ -739,35 +731,35 @@ def test_alias(self): # test no alias config["import"]["languages"] = [""] flat = mb._flatten_artist_credit([credit_dict]) - self.assertEqual(flat, ("NAME", "SORT", "CREDIT")) + assert flat == ("NAME", "SORT", "CREDIT") # test en primary config["import"]["languages"] = ["en"] flat = mb._flatten_artist_credit([credit_dict]) - self.assertEqual(flat, ("ALIASen", "ALIASSORTen", "CREDIT")) + assert flat == ("ALIASen", "ALIASSORTen", "CREDIT") # test en_GB en primary config["import"]["languages"] = ["en_GB", "en"] flat = mb._flatten_artist_credit([credit_dict]) - self.assertEqual(flat, ("ALIASen_GB", "ALIASSORTen_GB", "CREDIT")) + assert flat == ("ALIASen_GB", "ALIASSORTen_GB", "CREDIT") # test en en_GB primary config["import"]["languages"] = ["en", "en_GB"] flat = mb._flatten_artist_credit([credit_dict]) - self.assertEqual(flat, ("ALIASen", "ALIASSORTen", "CREDIT")) + assert flat == ("ALIASen", "ALIASSORTen", "CREDIT") # test fr primary config["import"]["languages"] = ["fr"] flat = mb._flatten_artist_credit([credit_dict]) - self.assertEqual(flat, ("ALIASfr_P", "ALIASSORTfr_P", "CREDIT")) + assert flat == ("ALIASfr_P", "ALIASSORTfr_P", "CREDIT") # test for not matching non-primary config["import"]["languages"] = ["pt_BR", "fr"] flat = mb._flatten_artist_credit([credit_dict]) - self.assertEqual(flat, ("ALIASfr_P", "ALIASSORTfr_P", "CREDIT")) + assert flat == ("ALIASfr_P", "ALIASSORTfr_P", "CREDIT") -class MBLibraryTest(unittest.TestCase): +class MBLibraryTest(BeetsTestCase): def test_match_track(self): with mock.patch("musicbrainzngs.search_recordings") as p: p.return_value = { @@ -782,8 +774,8 @@ def test_match_track(self): ti = list(mb.match_track("hello", "there"))[0] p.assert_called_with(artist="hello", recording="there", limit=5) - self.assertEqual(ti.title, "foo") - self.assertEqual(ti.track_id, "bar") + assert ti.title == "foo" + assert ti.track_id == "bar" def test_match_album(self): mbid = "d2a6f856-b553-40a0-ac54-a321e8e2da99" @@ -836,20 +828,20 @@ def test_match_album(self): sp.assert_called_with(artist="hello", release="there", limit=5) gp.assert_called_with(mbid, mock.ANY) - self.assertEqual(ai.tracks[0].title, "foo") - self.assertEqual(ai.album, "hi") + assert ai.tracks[0].title == "foo" + assert ai.album == "hi" def test_match_track_empty(self): with mock.patch("musicbrainzngs.search_recordings") as p: til = list(mb.match_track(" ", " ")) - self.assertFalse(p.called) - self.assertEqual(til, []) + assert not p.called + assert til == [] def test_match_album_empty(self): with mock.patch("musicbrainzngs.search_releases") as p: ail = list(mb.match_album(" ", " ")) - self.assertFalse(p.called) - self.assertEqual(ail, []) + assert not p.called + assert ail == [] def test_follow_pseudo_releases(self): side_effect = [ @@ -936,7 +928,7 @@ def test_follow_pseudo_releases(self): with mock.patch("musicbrainzngs.get_release_by_id") as gp: gp.side_effect = side_effect album = mb.album_for_id("d2a6f856-b553-40a0-ac54-a321e8e2da02") - self.assertEqual(album.country, "COUNTRY") + assert album.country == "COUNTRY" def test_pseudo_releases_with_empty_links(self): side_effect = [ @@ -981,7 +973,7 @@ def test_pseudo_releases_with_empty_links(self): with mock.patch("musicbrainzngs.get_release_by_id") as gp: gp.side_effect = side_effect album = mb.album_for_id("d2a6f856-b553-40a0-ac54-a321e8e2da02") - self.assertIsNone(album.country) + assert album.country is None def test_pseudo_releases_without_links(self): side_effect = [ @@ -1025,7 +1017,7 @@ def test_pseudo_releases_without_links(self): with mock.patch("musicbrainzngs.get_release_by_id") as gp: gp.side_effect = side_effect album = mb.album_for_id("d2a6f856-b553-40a0-ac54-a321e8e2da02") - self.assertIsNone(album.country) + assert album.country is None def test_pseudo_releases_with_unsupported_links(self): side_effect = [ @@ -1076,4 +1068,4 @@ def test_pseudo_releases_with_unsupported_links(self): with mock.patch("musicbrainzngs.get_release_by_id") as gp: gp.side_effect = side_effect album = mb.album_for_id("d2a6f856-b553-40a0-ac54-a321e8e2da02") - self.assertIsNone(album.country) + assert album.country is None diff --git a/test/test_metasync.py b/test/test_metasync.py index 4b97bf7d83..9e18a59ef0 100644 --- a/test/test_metasync.py +++ b/test/test_metasync.py @@ -84,46 +84,42 @@ def _set_up_data(self): def test_load_item_types(self): # This test also verifies that the MetaSources have loaded correctly - self.assertIn("amarok_score", Item._types) - self.assertIn("itunes_rating", Item._types) + assert "amarok_score" in Item._types + assert "itunes_rating" in Item._types def test_pretend_sync_from_itunes(self): out = self.run_with_output("metasync", "-p") - self.assertIn("itunes_rating: 60 -> 80", out) - self.assertIn("itunes_rating: 100", out) - self.assertIn("itunes_playcount: 31", out) - self.assertIn("itunes_skipcount: 3", out) - self.assertIn("itunes_lastplayed: 2015-05-04 12:20:51", out) - self.assertIn("itunes_lastskipped: 2015-02-05 15:41:04", out) - self.assertIn("itunes_dateadded: 2014-04-24 09:28:38", out) - self.assertEqual(self.lib.items()[0].itunes_rating, 60) + assert "itunes_rating: 60 -> 80" in out + assert "itunes_rating: 100" in out + assert "itunes_playcount: 31" in out + assert "itunes_skipcount: 3" in out + assert "itunes_lastplayed: 2015-05-04 12:20:51" in out + assert "itunes_lastskipped: 2015-02-05 15:41:04" in out + assert "itunes_dateadded: 2014-04-24 09:28:38" in out + assert self.lib.items()[0].itunes_rating == 60 def test_sync_from_itunes(self): self.run_command("metasync") - self.assertEqual(self.lib.items()[0].itunes_rating, 80) - self.assertEqual(self.lib.items()[0].itunes_playcount, 0) - self.assertEqual(self.lib.items()[0].itunes_skipcount, 3) - self.assertFalse(hasattr(self.lib.items()[0], "itunes_lastplayed")) - self.assertEqual( - self.lib.items()[0].itunes_lastskipped, - _parsetime("2015-02-05 15:41:04"), + assert self.lib.items()[0].itunes_rating == 80 + assert self.lib.items()[0].itunes_playcount == 0 + assert self.lib.items()[0].itunes_skipcount == 3 + assert not hasattr(self.lib.items()[0], "itunes_lastplayed") + assert self.lib.items()[0].itunes_lastskipped == _parsetime( + "2015-02-05 15:41:04" ) - self.assertEqual( - self.lib.items()[0].itunes_dateadded, - _parsetime("2014-04-24 09:28:38"), + assert self.lib.items()[0].itunes_dateadded == _parsetime( + "2014-04-24 09:28:38" ) - self.assertEqual(self.lib.items()[1].itunes_rating, 100) - self.assertEqual(self.lib.items()[1].itunes_playcount, 31) - self.assertEqual(self.lib.items()[1].itunes_skipcount, 0) - self.assertEqual( - self.lib.items()[1].itunes_lastplayed, - _parsetime("2015-05-04 12:20:51"), + assert self.lib.items()[1].itunes_rating == 100 + assert self.lib.items()[1].itunes_playcount == 31 + assert self.lib.items()[1].itunes_skipcount == 0 + assert self.lib.items()[1].itunes_lastplayed == _parsetime( + "2015-05-04 12:20:51" ) - self.assertEqual( - self.lib.items()[1].itunes_dateadded, - _parsetime("2014-04-24 09:28:38"), + assert self.lib.items()[1].itunes_dateadded == _parsetime( + "2014-04-24 09:28:38" ) - self.assertFalse(hasattr(self.lib.items()[1], "itunes_lastskipped")) + assert not hasattr(self.lib.items()[1], "itunes_lastskipped") diff --git a/test/test_pipeline.py b/test/test_pipeline.py index a1fa203f32..7b909dc27c 100644 --- a/test/test_pipeline.py +++ b/test/test_pipeline.py @@ -17,6 +17,8 @@ import unittest +import pytest + from beets.util import pipeline @@ -78,20 +80,20 @@ def setUp(self): def test_run_sequential(self): self.pl.run_sequential() - self.assertEqual(self.l, [0, 2, 4, 6, 8]) + assert self.l == [0, 2, 4, 6, 8] def test_run_parallel(self): self.pl.run_parallel() - self.assertEqual(self.l, [0, 2, 4, 6, 8]) + assert self.l == [0, 2, 4, 6, 8] def test_pull(self): pl = pipeline.Pipeline((_produce(), _work())) - self.assertEqual(list(pl.pull()), [0, 2, 4, 6, 8]) + assert list(pl.pull()) == [0, 2, 4, 6, 8] def test_pull_chain(self): pl = pipeline.Pipeline((_produce(), _work())) pl2 = pipeline.Pipeline((pl.pull(), _work())) - self.assertEqual(list(pl2.pull()), [0, 4, 8, 12, 16]) + assert list(pl2.pull()) == [0, 4, 8, 12, 16] class ParallelStageTest(unittest.TestCase): @@ -103,16 +105,16 @@ def setUp(self): def test_run_sequential(self): self.pl.run_sequential() - self.assertEqual(self.l, [0, 2, 4, 6, 8]) + assert self.l == [0, 2, 4, 6, 8] def test_run_parallel(self): self.pl.run_parallel() # Order possibly not preserved; use set equality. - self.assertEqual(set(self.l), {0, 2, 4, 6, 8}) + assert set(self.l) == {0, 2, 4, 6, 8} def test_pull(self): pl = pipeline.Pipeline((_produce(), (_work(), _work()))) - self.assertEqual(list(pl.pull()), [0, 2, 4, 6, 8]) + assert list(pl.pull()) == [0, 2, 4, 6, 8] class ExceptionTest(unittest.TestCase): @@ -121,17 +123,20 @@ def setUp(self): self.pl = pipeline.Pipeline((_produce(), _exc_work(), _consume(self.l))) def test_run_sequential(self): - self.assertRaises(ExceptionFixture, self.pl.run_sequential) + with pytest.raises(ExceptionFixture): + self.pl.run_sequential() def test_run_parallel(self): - self.assertRaises(ExceptionFixture, self.pl.run_parallel) + with pytest.raises(ExceptionFixture): + self.pl.run_parallel() def test_pull(self): pl = pipeline.Pipeline((_produce(), _exc_work())) pull = pl.pull() for i in range(3): next(pull) - self.assertRaises(ExceptionFixture, pull.__next__) + with pytest.raises(ExceptionFixture): + next(pull) class ParallelExceptionTest(unittest.TestCase): @@ -142,7 +147,8 @@ def setUp(self): ) def test_run_parallel(self): - self.assertRaises(ExceptionFixture, self.pl.run_parallel) + with pytest.raises(ExceptionFixture): + self.pl.run_parallel() class ConstrainedThreadedPipelineTest(unittest.TestCase): @@ -152,13 +158,14 @@ def test_constrained(self): pl = pipeline.Pipeline((_produce(1000), _work(), _consume(l))) # ... with only a single queue slot. pl.run_parallel(1) - self.assertEqual(l, [i * 2 for i in range(1000)]) + assert l == [i * 2 for i in range(1000)] def test_constrained_exception(self): # Raise an exception in a constrained pipeline. l = [] pl = pipeline.Pipeline((_produce(1000), _exc_work(), _consume(l))) - self.assertRaises(ExceptionFixture, pl.run_parallel, 1) + with pytest.raises(ExceptionFixture): + pl.run_parallel(1) def test_constrained_parallel(self): l = [] @@ -166,7 +173,7 @@ def test_constrained_parallel(self): (_produce(1000), (_work(), _work()), _consume(l)) ) pl.run_parallel(1) - self.assertEqual(set(l), {i * 2 for i in range(1000)}) + assert set(l) == {i * 2 for i in range(1000)} class BubbleTest(unittest.TestCase): @@ -176,15 +183,15 @@ def setUp(self): def test_run_sequential(self): self.pl.run_sequential() - self.assertEqual(self.l, [0, 2, 4, 8]) + assert self.l == [0, 2, 4, 8] def test_run_parallel(self): self.pl.run_parallel() - self.assertEqual(self.l, [0, 2, 4, 8]) + assert self.l == [0, 2, 4, 8] def test_pull(self): pl = pipeline.Pipeline((_produce(), _bub_work())) - self.assertEqual(list(pl.pull()), [0, 2, 4, 8]) + assert list(pl.pull()) == [0, 2, 4, 8] class MultiMessageTest(unittest.TestCase): @@ -196,15 +203,15 @@ def setUp(self): def test_run_sequential(self): self.pl.run_sequential() - self.assertEqual(self.l, [0, 0, 1, -1, 2, -2, 3, -3, 4, -4]) + assert self.l == [0, 0, 1, -1, 2, -2, 3, -3, 4, -4] def test_run_parallel(self): self.pl.run_parallel() - self.assertEqual(self.l, [0, 0, 1, -1, 2, -2, 3, -3, 4, -4]) + assert self.l == [0, 0, 1, -1, 2, -2, 3, -3, 4, -4] def test_pull(self): pl = pipeline.Pipeline((_produce(), _multi_work())) - self.assertEqual(list(pl.pull()), [0, 0, 1, -1, 2, -2, 3, -3, 4, -4]) + assert list(pl.pull()) == [0, 0, 1, -1, 2, -2, 3, -3, 4, -4] class StageDecoratorTest(unittest.TestCase): @@ -214,7 +221,7 @@ def add(n, i): return i + n pl = pipeline.Pipeline([iter([1, 2, 3]), add(2)]) - self.assertEqual(list(pl.pull()), [3, 4, 5]) + assert list(pl.pull()) == [3, 4, 5] def test_mutator_stage_decorator(self): @pipeline.mutator_stage @@ -222,11 +229,6 @@ def setkey(key, item): item[key] = True pl = pipeline.Pipeline( - [ - iter([{"x": False}, {"a": False}]), - setkey("x"), - ] - ) - self.assertEqual( - list(pl.pull()), [{"x": True}, {"a": False, "x": True}] + [iter([{"x": False}, {"a": False}]), setkey("x")] ) + assert list(pl.pull()) == [{"x": True}, {"a": False, "x": True}] diff --git a/test/test_plugins.py b/test/test_plugins.py index 709727d0a3..cb8d8e0d5e 100644 --- a/test/test_plugins.py +++ b/test/test_plugins.py @@ -18,6 +18,7 @@ import unittest from unittest.mock import ANY, Mock, patch +import pytest from mediafile import MediaFile from beets import config, plugins, ui @@ -89,17 +90,17 @@ class RatingPlugin(plugins.BeetsPlugin): # Do not match unset values out = self.run_with_output("ls", "rating:1..3") - self.assertNotIn("aaa", out) + assert "aaa" not in out self.run_command("modify", "rating=2", "--yes") # Match in range out = self.run_with_output("ls", "rating:1..3") - self.assertIn("aaa", out) + assert "aaa" in out # Don't match out of range out = self.run_with_output("ls", "rating:3..5") - self.assertNotIn("aaa", out) + assert "aaa" not in out class ItemWriteTest(PluginLoaderTestCase): @@ -123,7 +124,7 @@ def on_write(item=None, path=None, tags=None): item.write() mediafile = MediaFile(syspath(item.path)) - self.assertEqual(mediafile.artist, "YYY") + assert mediafile.artist == "YYY" def register_listener(self, event, func): self.event_listener_plugin.register_listener(event, func) @@ -141,7 +142,8 @@ class AdventListenerPlugin(plugins.BeetsPlugin): self.advent_listener_plugin = AdventListenerPlugin self.register_plugin(EventListenerPlugin) self.register_plugin(AdventListenerPlugin) - self.assertRaises(plugins.PluginConflictException, plugins.types, Item) + with pytest.raises(plugins.PluginConflictException): + plugins.types(Item) def test_match(self): class EventListenerPlugin(plugins.BeetsPlugin): @@ -154,7 +156,7 @@ class AdventListenerPlugin(plugins.BeetsPlugin): self.advent_listener_plugin = AdventListenerPlugin self.register_plugin(EventListenerPlugin) self.register_plugin(AdventListenerPlugin) - self.assertIsNotNone(plugins.types(Item)) + assert plugins.types(Item) is not None class EventsTest(PluginImportTestCase): @@ -169,19 +171,14 @@ def test_import_task_created(self): # Exactly one event should have been imported (for the album). # Sentinels do not get emitted. - self.assertEqual(logs.count("Sending event: import_task_created"), 1) + assert logs.count("Sending event: import_task_created") == 1 logs = [line for line in logs if not line.startswith("Sending event:")] - self.assertEqual( - logs, - [ - "Album: {}".format( - displayable_path(os.path.join(self.import_dir, b"album")) - ), - " {}".format(displayable_path(self.import_media[0].path)), - " {}".format(displayable_path(self.import_media[1].path)), - ], - ) + assert logs == [ + f'Album: {displayable_path(os.path.join(self.import_dir, b"album"))}', + f" {displayable_path(self.import_media[0].path)}", + f" {displayable_path(self.import_media[1].path)}", + ] def test_import_task_created_with_plugin(self): class ToSingletonPlugin(plugins.BeetsPlugin): @@ -216,32 +213,22 @@ def import_task_created_event(self, session, task): # Exactly one event should have been imported (for the album). # Sentinels do not get emitted. - self.assertEqual(logs.count("Sending event: import_task_created"), 1) + assert logs.count("Sending event: import_task_created") == 1 logs = [line for line in logs if not line.startswith("Sending event:")] - self.assertEqual( - logs, - [ - "Singleton: {}".format( - displayable_path(self.import_media[0].path) - ), - "Singleton: {}".format( - displayable_path(self.import_media[1].path) - ), - ], - ) + assert logs == [ + f"Singleton: {displayable_path(self.import_media[0].path)}", + f"Singleton: {displayable_path(self.import_media[1].path)}", + ] class HelpersTest(unittest.TestCase): def test_sanitize_choices(self): - self.assertEqual( - plugins.sanitize_choices(["A", "Z"], ("A", "B")), ["A"] - ) - self.assertEqual(plugins.sanitize_choices(["A", "A"], ("A")), ["A"]) - self.assertEqual( - plugins.sanitize_choices(["D", "*", "A"], ("A", "B", "C", "D")), - ["D", "B", "C", "A"], - ) + assert plugins.sanitize_choices(["A", "Z"], ("A", "B")) == ["A"] + assert plugins.sanitize_choices(["A", "A"], ("A")) == ["A"] + assert plugins.sanitize_choices( + ["D", "*", "A"], ("A", "B", "C", "D") + ) == ["D", "B", "C", "A"] class ListenersTest(PluginLoaderTestCase): @@ -256,17 +243,13 @@ def dummy(self): pass d = DummyPlugin() - self.assertEqual(DummyPlugin._raw_listeners["cli_exit"], [d.dummy]) + assert DummyPlugin._raw_listeners["cli_exit"] == [d.dummy] d2 = DummyPlugin() - self.assertEqual( - DummyPlugin._raw_listeners["cli_exit"], [d.dummy, d2.dummy] - ) + assert DummyPlugin._raw_listeners["cli_exit"] == [d.dummy, d2.dummy] d.register_listener("cli_exit", d2.dummy) - self.assertEqual( - DummyPlugin._raw_listeners["cli_exit"], [d.dummy, d2.dummy] - ) + assert DummyPlugin._raw_listeners["cli_exit"] == [d.dummy, d2.dummy] @patch("beets.plugins.find_plugins") @patch("inspect.getfullargspec") @@ -298,7 +281,6 @@ def __init__(self): @patch("beets.plugins.find_plugins") def test_listener_params(self, mock_find_plugins): - test = self class DummyPlugin(plugins.BeetsPlugin): def __init__(self): @@ -311,10 +293,10 @@ def __init__(self): self.register_listener(f"event{i}", meth) def dummy1(self, foo): - test.assertEqual(foo, 5) + assert foo == 5 def dummy2(self, foo=None): - test.assertEqual(foo, 5) + assert foo == 5 def dummy3(self): # argument cut off @@ -325,23 +307,23 @@ def dummy4(self, bar=None): pass def dummy5(self, bar): - test.assertFalse(True) + assert not True # more complex examples def dummy6(self, foo, bar=None): - test.assertEqual(foo, 5) - test.assertEqual(bar, None) + assert foo == 5 + assert bar is None def dummy7(self, foo, **kwargs): - test.assertEqual(foo, 5) - test.assertEqual(kwargs, {}) + assert foo == 5 + assert kwargs == {} def dummy8(self, foo, bar, **kwargs): - test.assertFalse(True) + assert not True def dummy9(self, **kwargs): - test.assertEqual(kwargs, {"foo": 5}) + assert kwargs == {"foo": 5} d = DummyPlugin() mock_find_plugins.return_value = (d,) @@ -351,13 +333,13 @@ def dummy9(self, **kwargs): plugins.send("event3", foo=5) plugins.send("event4", foo=5) - with self.assertRaises(TypeError): + with pytest.raises(TypeError): plugins.send("event5", foo=5) plugins.send("event6", foo=5) plugins.send("event7", foo=5) - with self.assertRaises(TypeError): + with pytest.raises(TypeError): plugins.send("event8", foo=5) plugins.send("event9", foo=5) @@ -521,10 +503,10 @@ def foo(self, session, task): with patch.object(DummyPlugin, "foo", autospec=True) as mock_foo: with helper.control_stdin("\n".join(["f", "s"])): self.importer.run() - self.assertEqual(mock_foo.call_count, 1) + assert mock_foo.call_count == 1 # input_options should be called twice, as foo() returns None - self.assertEqual(self.mock_input_options.call_count, 2) + assert self.mock_input_options.call_count == 2 self.mock_input_options.assert_called_with( opts, default="a", require=ANY ) @@ -573,36 +555,36 @@ class ParseSpotifyIDTest(unittest.TestCase): def test_parse_id_correct(self): id_string = "39WqpoPgZxygo6YQjehLJJ" out = MetadataSourcePlugin._get_id("album", id_string, spotify_id_regex) - self.assertEqual(out, id_string) + assert out == id_string def test_parse_id_non_id_returns_none(self): id_string = "blah blah" out = MetadataSourcePlugin._get_id("album", id_string, spotify_id_regex) - self.assertIsNone(out) + assert out is None def test_parse_id_url_finds_id(self): id_string = "39WqpoPgZxygo6YQjehLJJ" id_url = "https://open.spotify.com/album/%s" % id_string out = MetadataSourcePlugin._get_id("album", id_url, spotify_id_regex) - self.assertEqual(out, id_string) + assert out == id_string class ParseDeezerIDTest(unittest.TestCase): def test_parse_id_correct(self): id_string = "176356382" out = MetadataSourcePlugin._get_id("album", id_string, deezer_id_regex) - self.assertEqual(out, id_string) + assert out == id_string def test_parse_id_non_id_returns_none(self): id_string = "blah blah" out = MetadataSourcePlugin._get_id("album", id_string, deezer_id_regex) - self.assertIsNone(out) + assert out is None def test_parse_id_url_finds_id(self): id_string = "176356382" id_url = "https://www.deezer.com/album/%s" % id_string out = MetadataSourcePlugin._get_id("album", id_url, deezer_id_regex) - self.assertEqual(out, id_string) + assert out == id_string class ParseBeatportIDTest(unittest.TestCase): @@ -611,17 +593,17 @@ def test_parse_id_correct(self): out = MetadataSourcePlugin._get_id( "album", id_string, beatport_id_regex ) - self.assertEqual(out, id_string) + assert out == id_string def test_parse_id_non_id_returns_none(self): id_string = "blah blah" out = MetadataSourcePlugin._get_id( "album", id_string, beatport_id_regex ) - self.assertIsNone(out) + assert out is None def test_parse_id_url_finds_id(self): id_string = "3089651" id_url = "https://www.beatport.com/release/album-name/%s" % id_string out = MetadataSourcePlugin._get_id("album", id_url, beatport_id_regex) - self.assertEqual(out, id_string) + assert out == id_string diff --git a/test/test_query.py b/test/test_query.py index cdfcc7eedb..04170a1598 100644 --- a/test/test_query.py +++ b/test/test_query.py @@ -21,6 +21,8 @@ from contextlib import contextmanager from functools import partial +import pytest + import beets.library from beets import dbcore, util from beets.dbcore import types @@ -41,18 +43,18 @@ class AssertsMixin: def assert_items_matched(self, results, titles): - self.assertEqual({i.title for i in results}, set(titles)) + assert {i.title for i in results} == set(titles) def assert_albums_matched(self, results, albums): - self.assertEqual({a.album for a in results}, set(albums)) + assert {a.album for a in results} == set(albums) def assertInResult(self, item, results): # noqa result_ids = [i.id for i in results] - self.assertIn(item.id, result_ids) + assert item.id in result_ids def assertNotInResult(self, item, results): # noqa result_ids = [i.id for i in results] - self.assertNotIn(item.id, result_ids) + assert item.id not in result_ids class AnyFieldQueryTest(ItemInDBTestCase): @@ -62,19 +64,19 @@ def test_no_restriction(self): beets.library.Item._fields.keys(), dbcore.query.SubstringQuery, ) - self.assertEqual(self.lib.items(q).get().title, "the title") + assert self.lib.items(q).get().title == "the title" def test_restriction_completeness(self): q = dbcore.query.AnyFieldQuery( "title", ["title"], dbcore.query.SubstringQuery ) - self.assertEqual(self.lib.items(q).get().title, "the title") + assert self.lib.items(q).get().title == "the title" def test_restriction_soundness(self): q = dbcore.query.AnyFieldQuery( "title", ["artist"], dbcore.query.SubstringQuery ) - self.assertIsNone(self.lib.items(q).get()) + assert self.lib.items(q).get() is None def test_eq(self): q1 = dbcore.query.AnyFieldQuery( @@ -83,10 +85,10 @@ def test_eq(self): q2 = dbcore.query.AnyFieldQuery( "foo", ["bar"], dbcore.query.SubstringQuery ) - self.assertEqual(q1, q2) + assert q1 == q2 q2.query_class = None - self.assertNotEqual(q1, q2) + assert q1 != q2 # A test case class providing a library with some dummy data and some @@ -356,19 +358,19 @@ def test_unknown_field_name_no_results(self): q = "xyzzy:nonsense" results = self.lib.items(q) titles = [i.title for i in results] - self.assertEqual(titles, []) + assert titles == [] def test_unknown_field_name_no_results_in_album_query(self): q = "xyzzy:nonsense" results = self.lib.albums(q) names = [a.album for a in results] - self.assertEqual(names, []) + assert names == [] def test_item_field_name_matches_nothing_in_album_query(self): q = "format:nonsense" results = self.lib.albums(q) names = [a.album for a in results] - self.assertEqual(names, []) + assert names == [] def test_unicode_query(self): item = self.lib.items().get() @@ -382,12 +384,12 @@ def test_unicode_query(self): def test_numeric_search_positive(self): q = dbcore.query.NumericQuery("year", "2001") results = self.lib.items(q) - self.assertTrue(results) + assert results def test_numeric_search_negative(self): q = dbcore.query.NumericQuery("year", "1999") results = self.lib.items(q) - self.assertFalse(results) + assert not results def test_album_field_fallback(self): self.album["albumflex"] = "foo" @@ -395,25 +397,15 @@ def test_album_field_fallback(self): q = "albumflex:foo" results = self.lib.items(q) - self.assert_items_matched( - results, - [ - "foo bar", - "baz qux", - ], - ) + self.assert_items_matched(results, ["foo bar", "baz qux"]) def test_invalid_query(self): - with self.assertRaises(InvalidQueryArgumentValueError) as raised: + with pytest.raises(InvalidQueryArgumentValueError, match="not an int"): dbcore.query.NumericQuery("year", "199a") - self.assertIn("not an int", str(raised.exception)) - with self.assertRaises(InvalidQueryArgumentValueError) as raised: + msg_match = r"not a regular expression.*unterminated subpattern" + with pytest.raises(ParsingError, match=msg_match): dbcore.query.RegexpQuery("year", "199(") - exception_text = str(raised.exception) - self.assertIn("not a regular expression", exception_text) - self.assertIn("unterminated subpattern", exception_text) - self.assertIsInstance(raised.exception, ParsingError) class MatchTest(BeetsTestCase): @@ -423,53 +415,53 @@ def setUp(self): def test_regex_match_positive(self): q = dbcore.query.RegexpQuery("album", "^the album$") - self.assertTrue(q.match(self.item)) + assert q.match(self.item) def test_regex_match_negative(self): q = dbcore.query.RegexpQuery("album", "^album$") - self.assertFalse(q.match(self.item)) + assert not q.match(self.item) def test_regex_match_non_string_value(self): q = dbcore.query.RegexpQuery("disc", "^6$") - self.assertTrue(q.match(self.item)) + assert q.match(self.item) def test_substring_match_positive(self): q = dbcore.query.SubstringQuery("album", "album") - self.assertTrue(q.match(self.item)) + assert q.match(self.item) def test_substring_match_negative(self): q = dbcore.query.SubstringQuery("album", "ablum") - self.assertFalse(q.match(self.item)) + assert not q.match(self.item) def test_substring_match_non_string_value(self): q = dbcore.query.SubstringQuery("disc", "6") - self.assertTrue(q.match(self.item)) + assert q.match(self.item) def test_exact_match_nocase_positive(self): q = dbcore.query.StringQuery("genre", "the genre") - self.assertTrue(q.match(self.item)) + assert q.match(self.item) q = dbcore.query.StringQuery("genre", "THE GENRE") - self.assertTrue(q.match(self.item)) + assert q.match(self.item) def test_exact_match_nocase_negative(self): q = dbcore.query.StringQuery("genre", "genre") - self.assertFalse(q.match(self.item)) + assert not q.match(self.item) def test_year_match_positive(self): q = dbcore.query.NumericQuery("year", "1") - self.assertTrue(q.match(self.item)) + assert q.match(self.item) def test_year_match_negative(self): q = dbcore.query.NumericQuery("year", "10") - self.assertFalse(q.match(self.item)) + assert not q.match(self.item) def test_bitrate_range_positive(self): q = dbcore.query.NumericQuery("bitrate", "100000..200000") - self.assertTrue(q.match(self.item)) + assert q.match(self.item) def test_bitrate_range_negative(self): q = dbcore.query.NumericQuery("bitrate", "200000..300000") - self.assertFalse(q.match(self.item)) + assert not q.match(self.item) def test_open_range(self): dbcore.query.NumericQuery("bitrate", "100000..") @@ -479,10 +471,10 @@ def test_eq(self): q2 = dbcore.query.MatchQuery("foo", "bar") q3 = dbcore.query.MatchQuery("foo", "baz") q4 = dbcore.query.StringFieldQuery("foo", "bar") - self.assertEqual(q1, q2) - self.assertNotEqual(q1, q3) - self.assertNotEqual(q1, q4) - self.assertNotEqual(q3, q4) + assert q1 == q2 + assert q1 != q3 + assert q1 != q4 + assert q3 != q4 class PathQueryTest(ItemInDBTestCase, AssertsMixin): @@ -667,13 +659,13 @@ def test_path_sep_detection(self): is_path_query = beets.library.PathQuery.is_path_query with self.force_implicit_query_detection(): - self.assertTrue(is_path_query("/foo/bar")) - self.assertTrue(is_path_query("foo/bar")) - self.assertTrue(is_path_query("foo/")) - self.assertFalse(is_path_query("foo")) - self.assertTrue(is_path_query("foo/:bar")) - self.assertFalse(is_path_query("foo:bar/")) - self.assertFalse(is_path_query("foo:/bar")) + assert is_path_query("/foo/bar") + assert is_path_query("foo/bar") + assert is_path_query("foo/") + assert not is_path_query("foo") + assert is_path_query("foo/:bar") + assert not is_path_query("foo:bar/") + assert not is_path_query("foo:/bar") # FIXME: shouldn't this also work on windows? @unittest.skipIf(sys.platform == "win32", WIN32_NO_IMPLICIT_PATHS) @@ -687,18 +679,18 @@ def test_detect_absolute_path(self): is_path_query = beets.library.PathQuery.is_path_query path = self.touch(os.path.join(b"foo", b"bar")) - self.assertTrue(os.path.isabs(util.syspath(path))) + assert os.path.isabs(util.syspath(path)) path_str = path.decode("utf-8") # The file itself. - self.assertTrue(is_path_query(path_str)) + assert is_path_query(path_str) # The parent directory. parent = os.path.dirname(path_str) - self.assertTrue(is_path_query(parent)) + assert is_path_query(parent) # Some non-existent path. - self.assertFalse(is_path_query(path_str + "baz")) + assert not is_path_query(f"{path_str}baz") def test_detect_relative_path(self): """Test detection of implicit path queries based on whether or @@ -715,10 +707,10 @@ def test_detect_relative_path(self): cur_dir = os.getcwd() try: os.chdir(syspath(self.temp_dir)) - self.assertTrue(is_path_query("foo/")) - self.assertTrue(is_path_query("foo/bar")) - self.assertTrue(is_path_query("foo/bar:tagada")) - self.assertFalse(is_path_query("bar")) + assert is_path_query("foo/") + assert is_path_query("foo/bar") + assert is_path_query("foo/bar:tagada") + assert not is_path_query("bar") finally: os.chdir(cur_dir) @@ -731,32 +723,32 @@ def tearDown(self): def test_exact_value_match(self): item = self.add_item(bpm=120) matched = self.lib.items("bpm:120").get() - self.assertEqual(item.id, matched.id) + assert item.id == matched.id def test_range_match(self): item = self.add_item(bpm=120) self.add_item(bpm=130) matched = self.lib.items("bpm:110..125") - self.assertEqual(1, len(matched)) - self.assertEqual(item.id, matched.get().id) + assert 1 == len(matched) + assert item.id == matched.get().id def test_flex_range_match(self): Item._types = {"myint": types.Integer()} item = self.add_item(myint=2) matched = self.lib.items("myint:2").get() - self.assertEqual(item.id, matched.id) + assert item.id == matched.id def test_flex_dont_match_missing(self): Item._types = {"myint": types.Integer()} self.add_item() matched = self.lib.items("myint:2").get() - self.assertIsNone(matched) + assert matched is None def test_no_substring_match(self): self.add_item(bpm=120) matched = self.lib.items("bpm:12").get() - self.assertIsNone(matched) + assert matched is None class BoolQueryTest(BeetsTestCase, AssertsMixin): @@ -815,11 +807,11 @@ def test_flex_parse_any_string(self): class DefaultSearchFieldsTest(DummyDataTestCase): def test_albums_matches_album(self): albums = list(self.lib.albums("baz")) - self.assertEqual(len(albums), 1) + assert len(albums) == 1 def test_albums_matches_albumartist(self): albums = list(self.lib.albums(["album artist"])) - self.assertEqual(len(albums), 1) + assert len(albums) == 1 def test_items_matches_title(self): items = self.lib.items("beets") @@ -868,7 +860,7 @@ def test_match_slow_after_set_none(self): 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))). + queries (ie. assert q -> assert not NotQuery(q)). """ def setUp(self): @@ -877,53 +869,53 @@ def setUp(self): def test_regex_match_positive(self): q = dbcore.query.RegexpQuery("album", "^the album$") - self.assertTrue(q.match(self.item)) - self.assertFalse(dbcore.query.NotQuery(q).match(self.item)) + assert q.match(self.item) + assert not dbcore.query.NotQuery(q).match(self.item) def test_regex_match_negative(self): q = dbcore.query.RegexpQuery("album", "^album$") - self.assertFalse(q.match(self.item)) - self.assertTrue(dbcore.query.NotQuery(q).match(self.item)) + assert not q.match(self.item) + assert dbcore.query.NotQuery(q).match(self.item) def test_regex_match_non_string_value(self): q = dbcore.query.RegexpQuery("disc", "^6$") - self.assertTrue(q.match(self.item)) - self.assertFalse(dbcore.query.NotQuery(q).match(self.item)) + assert q.match(self.item) + assert not dbcore.query.NotQuery(q).match(self.item) def test_substring_match_positive(self): q = dbcore.query.SubstringQuery("album", "album") - self.assertTrue(q.match(self.item)) - self.assertFalse(dbcore.query.NotQuery(q).match(self.item)) + assert q.match(self.item) + assert not dbcore.query.NotQuery(q).match(self.item) def test_substring_match_negative(self): q = dbcore.query.SubstringQuery("album", "ablum") - self.assertFalse(q.match(self.item)) - self.assertTrue(dbcore.query.NotQuery(q).match(self.item)) + assert not q.match(self.item) + assert dbcore.query.NotQuery(q).match(self.item) def test_substring_match_non_string_value(self): q = dbcore.query.SubstringQuery("disc", "6") - self.assertTrue(q.match(self.item)) - self.assertFalse(dbcore.query.NotQuery(q).match(self.item)) + assert q.match(self.item) + assert not dbcore.query.NotQuery(q).match(self.item) def test_year_match_positive(self): q = dbcore.query.NumericQuery("year", "1") - self.assertTrue(q.match(self.item)) - self.assertFalse(dbcore.query.NotQuery(q).match(self.item)) + assert q.match(self.item) + assert not dbcore.query.NotQuery(q).match(self.item) def test_year_match_negative(self): q = dbcore.query.NumericQuery("year", "10") - self.assertFalse(q.match(self.item)) - self.assertTrue(dbcore.query.NotQuery(q).match(self.item)) + assert not q.match(self.item) + assert dbcore.query.NotQuery(q).match(self.item) def test_bitrate_range_positive(self): q = dbcore.query.NumericQuery("bitrate", "100000..200000") - self.assertTrue(q.match(self.item)) - self.assertFalse(dbcore.query.NotQuery(q).match(self.item)) + assert q.match(self.item) + assert not dbcore.query.NotQuery(q).match(self.item) def test_bitrate_range_negative(self): q = dbcore.query.NumericQuery("bitrate", "200000..300000") - self.assertFalse(q.match(self.item)) - self.assertTrue(dbcore.query.NotQuery(q).match(self.item)) + assert not q.match(self.item) + assert dbcore.query.NotQuery(q).match(self.item) def test_open_range(self): q = dbcore.query.NumericQuery("bitrate", "100000..") @@ -953,15 +945,14 @@ def assertNegationProperties(self, q): # noqa all_titles = {i.title for i in self.lib.items()} q_results = {i.title for i in self.lib.items(q)} not_q_results = {i.title for i in self.lib.items(not_q)} - self.assertEqual(q_results.union(not_q_results), all_titles) - self.assertEqual(q_results.intersection(not_q_results), set()) + assert q_results.union(not_q_results) == all_titles + assert q_results.intersection(not_q_results) == set() # round trip not_not_q = dbcore.query.NotQuery(not_q) - self.assertEqual( - {i.title for i in self.lib.items(q)}, - {i.title for i in self.lib.items(not_not_q)}, - ) + assert {i.title for i in self.lib.items(q)} == { + i.title for i in self.lib.items(not_not_q) + } def test_type_and(self): # not(a and b) <-> not(a) or not(b) @@ -1114,10 +1105,9 @@ def test_fast_vs_slow(self): q_slow = dbcore.query.NotQuery(klass(*(args + [False]))) try: - self.assertEqual( - [i.title for i in self.lib.items(q_fast)], - [i.title for i in self.lib.items(q_slow)], - ) + assert [i.title for i in self.lib.items(q_fast)] == [ + i.title for i in self.lib.items(q_slow) + ] except NotImplementedError: # ignore classes that do not provide `fast` implementation pass diff --git a/test/test_sort.py b/test/test_sort.py index d602c6cbac..3d27f6591d 100644 --- a/test/test_sort.py +++ b/test/test_sort.py @@ -107,25 +107,25 @@ def test_sort_asc(self): q = "" sort = dbcore.query.FixedFieldSort("year", True) results = self.lib.items(q, sort) - self.assertLessEqual(results[0]["year"], results[1]["year"]) - self.assertEqual(results[0]["year"], 2001) + assert results[0]["year"] <= results[1]["year"] + assert results[0]["year"] == 2001 # same thing with query string q = "year+" results2 = self.lib.items(q) for r1, r2 in zip(results, results2): - self.assertEqual(r1.id, r2.id) + assert r1.id == r2.id def test_sort_desc(self): q = "" sort = dbcore.query.FixedFieldSort("year", False) results = self.lib.items(q, sort) - self.assertGreaterEqual(results[0]["year"], results[1]["year"]) - self.assertEqual(results[0]["year"], 2004) + assert results[0]["year"] >= results[1]["year"] + assert results[0]["year"] == 2004 # same thing with query string q = "year-" results2 = self.lib.items(q) for r1, r2 in zip(results, results2): - self.assertEqual(r1.id, r2.id) + assert r1.id == r2.id def test_sort_two_field_asc(self): q = "" @@ -135,25 +135,25 @@ def test_sort_two_field_asc(self): sort.add_sort(s1) sort.add_sort(s2) results = self.lib.items(q, sort) - self.assertLessEqual(results[0]["album"], results[1]["album"]) - self.assertLessEqual(results[1]["album"], results[2]["album"]) - self.assertEqual(results[0]["album"], "Baz") - self.assertEqual(results[1]["album"], "Baz") - self.assertLessEqual(results[0]["year"], results[1]["year"]) + assert results[0]["album"] <= results[1]["album"] + assert results[1]["album"] <= results[2]["album"] + assert results[0]["album"] == "Baz" + assert results[1]["album"] == "Baz" + assert results[0]["year"] <= results[1]["year"] # same thing with query string q = "album+ year+" results2 = self.lib.items(q) for r1, r2 in zip(results, results2): - self.assertEqual(r1.id, r2.id) + assert r1.id == r2.id def test_sort_path_field(self): q = "" sort = dbcore.query.FixedFieldSort("path", True) results = self.lib.items(q, sort) - self.assertEqual(results[0]["path"], b"/path0.mp3") - self.assertEqual(results[1]["path"], b"/patH1.mp3") - self.assertEqual(results[2]["path"], b"/paTH2.mp3") - self.assertEqual(results[3]["path"], b"/PATH3.mp3") + assert results[0]["path"] == b"/path0.mp3" + assert results[1]["path"] == b"/patH1.mp3" + assert results[2]["path"] == b"/paTH2.mp3" + assert results[3]["path"] == b"/PATH3.mp3" class SortFlexFieldTest(DummyDataTestCase): @@ -161,27 +161,27 @@ def test_sort_asc(self): q = "" sort = dbcore.query.SlowFieldSort("flex1", True) results = self.lib.items(q, sort) - self.assertLessEqual(results[0]["flex1"], results[1]["flex1"]) - self.assertEqual(results[0]["flex1"], "Flex1-0") + assert results[0]["flex1"] <= results[1]["flex1"] + assert results[0]["flex1"] == "Flex1-0" # same thing with query string q = "flex1+" results2 = self.lib.items(q) for r1, r2 in zip(results, results2): - self.assertEqual(r1.id, r2.id) + assert r1.id == r2.id def test_sort_desc(self): q = "" sort = dbcore.query.SlowFieldSort("flex1", False) results = self.lib.items(q, sort) - self.assertGreaterEqual(results[0]["flex1"], results[1]["flex1"]) - self.assertGreaterEqual(results[1]["flex1"], results[2]["flex1"]) - self.assertGreaterEqual(results[2]["flex1"], results[3]["flex1"]) - self.assertEqual(results[0]["flex1"], "Flex1-2") + assert results[0]["flex1"] >= results[1]["flex1"] + assert results[1]["flex1"] >= results[2]["flex1"] + assert results[2]["flex1"] >= results[3]["flex1"] + assert results[0]["flex1"] == "Flex1-2" # same thing with query string q = "flex1-" results2 = self.lib.items(q) for r1, r2 in zip(results, results2): - self.assertEqual(r1.id, r2.id) + assert r1.id == r2.id def test_sort_two_field(self): q = "" @@ -191,16 +191,16 @@ def test_sort_two_field(self): sort.add_sort(s1) sort.add_sort(s2) results = self.lib.items(q, sort) - self.assertGreaterEqual(results[0]["flex2"], results[1]["flex2"]) - self.assertGreaterEqual(results[1]["flex2"], results[2]["flex2"]) - self.assertEqual(results[0]["flex2"], "Flex2-A") - self.assertEqual(results[1]["flex2"], "Flex2-A") - self.assertLessEqual(results[0]["flex1"], results[1]["flex1"]) + assert results[0]["flex2"] >= results[1]["flex2"] + assert results[1]["flex2"] >= results[2]["flex2"] + assert results[0]["flex2"] == "Flex2-A" + assert results[1]["flex2"] == "Flex2-A" + assert results[0]["flex1"] <= results[1]["flex1"] # same thing with query string q = "flex2- flex1+" results2 = self.lib.items(q) for r1, r2 in zip(results, results2): - self.assertEqual(r1.id, r2.id) + assert r1.id == r2.id class SortAlbumFixedFieldTest(DummyDataTestCase): @@ -208,25 +208,25 @@ def test_sort_asc(self): q = "" sort = dbcore.query.FixedFieldSort("year", True) results = self.lib.albums(q, sort) - self.assertLessEqual(results[0]["year"], results[1]["year"]) - self.assertEqual(results[0]["year"], 2001) + assert results[0]["year"] <= results[1]["year"] + assert results[0]["year"] == 2001 # same thing with query string q = "year+" results2 = self.lib.albums(q) for r1, r2 in zip(results, results2): - self.assertEqual(r1.id, r2.id) + assert r1.id == r2.id def test_sort_desc(self): q = "" sort = dbcore.query.FixedFieldSort("year", False) results = self.lib.albums(q, sort) - self.assertGreaterEqual(results[0]["year"], results[1]["year"]) - self.assertEqual(results[0]["year"], 2005) + assert results[0]["year"] >= results[1]["year"] + assert results[0]["year"] == 2005 # same thing with query string q = "year-" results2 = self.lib.albums(q) for r1, r2 in zip(results, results2): - self.assertEqual(r1.id, r2.id) + assert r1.id == r2.id def test_sort_two_field_asc(self): q = "" @@ -236,16 +236,16 @@ def test_sort_two_field_asc(self): sort.add_sort(s1) sort.add_sort(s2) results = self.lib.albums(q, sort) - self.assertLessEqual(results[0]["genre"], results[1]["genre"]) - self.assertLessEqual(results[1]["genre"], results[2]["genre"]) - self.assertEqual(results[1]["genre"], "Rock") - self.assertEqual(results[2]["genre"], "Rock") - self.assertLessEqual(results[1]["album"], results[2]["album"]) + assert results[0]["genre"] <= results[1]["genre"] + assert results[1]["genre"] <= results[2]["genre"] + assert results[1]["genre"] == "Rock" + assert results[2]["genre"] == "Rock" + assert results[1]["album"] <= results[2]["album"] # same thing with query string q = "genre+ album+" results2 = self.lib.albums(q) for r1, r2 in zip(results, results2): - self.assertEqual(r1.id, r2.id) + assert r1.id == r2.id class SortAlbumFlexFieldTest(DummyDataTestCase): @@ -253,25 +253,25 @@ def test_sort_asc(self): q = "" sort = dbcore.query.SlowFieldSort("flex1", True) results = self.lib.albums(q, sort) - self.assertLessEqual(results[0]["flex1"], results[1]["flex1"]) - self.assertLessEqual(results[1]["flex1"], results[2]["flex1"]) + assert results[0]["flex1"] <= results[1]["flex1"] + assert results[1]["flex1"] <= results[2]["flex1"] # same thing with query string q = "flex1+" results2 = self.lib.albums(q) for r1, r2 in zip(results, results2): - self.assertEqual(r1.id, r2.id) + assert r1.id == r2.id def test_sort_desc(self): q = "" sort = dbcore.query.SlowFieldSort("flex1", False) results = self.lib.albums(q, sort) - self.assertGreaterEqual(results[0]["flex1"], results[1]["flex1"]) - self.assertGreaterEqual(results[1]["flex1"], results[2]["flex1"]) + assert results[0]["flex1"] >= results[1]["flex1"] + assert results[1]["flex1"] >= results[2]["flex1"] # same thing with query string q = "flex1-" results2 = self.lib.albums(q) for r1, r2 in zip(results, results2): - self.assertEqual(r1.id, r2.id) + assert r1.id == r2.id def test_sort_two_field_asc(self): q = "" @@ -281,16 +281,16 @@ def test_sort_two_field_asc(self): sort.add_sort(s1) sort.add_sort(s2) results = self.lib.albums(q, sort) - self.assertLessEqual(results[0]["flex2"], results[1]["flex2"]) - self.assertLessEqual(results[1]["flex2"], results[2]["flex2"]) - self.assertEqual(results[0]["flex2"], "Flex2-A") - self.assertEqual(results[1]["flex2"], "Flex2-A") - self.assertLessEqual(results[0]["flex1"], results[1]["flex1"]) + assert results[0]["flex2"] <= results[1]["flex2"] + assert results[1]["flex2"] <= results[2]["flex2"] + assert results[0]["flex2"] == "Flex2-A" + assert results[1]["flex2"] == "Flex2-A" + assert results[0]["flex1"] <= results[1]["flex1"] # same thing with query string q = "flex2+ flex1+" results2 = self.lib.albums(q) for r1, r2 in zip(results, results2): - self.assertEqual(r1.id, r2.id) + assert r1.id == r2.id class SortAlbumComputedFieldTest(DummyDataTestCase): @@ -298,25 +298,25 @@ def test_sort_asc(self): q = "" sort = dbcore.query.SlowFieldSort("path", True) results = self.lib.albums(q, sort) - self.assertLessEqual(results[0]["path"], results[1]["path"]) - self.assertLessEqual(results[1]["path"], results[2]["path"]) + assert results[0]["path"] <= results[1]["path"] + assert results[1]["path"] <= results[2]["path"] # same thing with query string q = "path+" results2 = self.lib.albums(q) for r1, r2 in zip(results, results2): - self.assertEqual(r1.id, r2.id) + assert r1.id == r2.id def test_sort_desc(self): q = "" sort = dbcore.query.SlowFieldSort("path", False) results = self.lib.albums(q, sort) - self.assertGreaterEqual(results[0]["path"], results[1]["path"]) - self.assertGreaterEqual(results[1]["path"], results[2]["path"]) + assert results[0]["path"] >= results[1]["path"] + assert results[1]["path"] >= results[2]["path"] # same thing with query string q = "path-" results2 = self.lib.albums(q) for r1, r2 in zip(results, results2): - self.assertEqual(r1.id, r2.id) + assert r1.id == r2.id class SortCombinedFieldTest(DummyDataTestCase): @@ -328,12 +328,12 @@ def test_computed_first(self): sort.add_sort(s1) sort.add_sort(s2) results = self.lib.albums(q, sort) - self.assertLessEqual(results[0]["path"], results[1]["path"]) - self.assertLessEqual(results[1]["path"], results[2]["path"]) + assert results[0]["path"] <= results[1]["path"] + assert results[1]["path"] <= results[2]["path"] q = "path+ year+" results2 = self.lib.albums(q) for r1, r2 in zip(results, results2): - self.assertEqual(r1.id, r2.id) + assert r1.id == r2.id def test_computed_second(self): q = "" @@ -343,33 +343,33 @@ def test_computed_second(self): sort.add_sort(s1) sort.add_sort(s2) results = self.lib.albums(q, sort) - self.assertLessEqual(results[0]["year"], results[1]["year"]) - self.assertLessEqual(results[1]["year"], results[2]["year"]) - self.assertLessEqual(results[0]["path"], results[1]["path"]) + assert results[0]["year"] <= results[1]["year"] + assert results[1]["year"] <= results[2]["year"] + assert results[0]["path"] <= results[1]["path"] q = "year+ path+" results2 = self.lib.albums(q) for r1, r2 in zip(results, results2): - self.assertEqual(r1.id, r2.id) + assert r1.id == r2.id class ConfigSortTest(DummyDataTestCase): def test_default_sort_item(self): results = list(self.lib.items()) - self.assertLess(results[0].artist, results[1].artist) + assert results[0].artist < results[1].artist def test_config_opposite_sort_item(self): config["sort_item"] = "artist-" results = list(self.lib.items()) - self.assertGreater(results[0].artist, results[1].artist) + assert results[0].artist > results[1].artist def test_default_sort_album(self): results = list(self.lib.albums()) - self.assertLess(results[0].albumartist, results[1].albumartist) + assert results[0].albumartist < results[1].albumartist def test_config_opposite_sort_album(self): config["sort_album"] = "albumartist-" results = list(self.lib.albums()) - self.assertGreater(results[0].albumartist, results[1].albumartist) + assert results[0].albumartist > results[1].albumartist class CaseSensitivityTest(DummyDataTestCase, BeetsTestCase): @@ -415,43 +415,43 @@ def test_smart_artist_case_insensitive(self): config["sort_case_insensitive"] = True q = "artist+" results = list(self.lib.items(q)) - self.assertEqual(results[0].artist, "lowercase") - self.assertEqual(results[1].artist, "One") + assert results[0].artist == "lowercase" + assert results[1].artist == "One" def test_smart_artist_case_sensitive(self): config["sort_case_insensitive"] = False q = "artist+" results = list(self.lib.items(q)) - self.assertEqual(results[0].artist, "One") - self.assertEqual(results[-1].artist, "lowercase") + assert results[0].artist == "One" + assert results[-1].artist == "lowercase" def test_fixed_field_case_insensitive(self): config["sort_case_insensitive"] = True q = "album+" results = list(self.lib.albums(q)) - self.assertEqual(results[0].album, "album") - self.assertEqual(results[1].album, "Album A") + assert results[0].album == "album" + assert results[1].album == "Album A" def test_fixed_field_case_sensitive(self): config["sort_case_insensitive"] = False q = "album+" results = list(self.lib.albums(q)) - self.assertEqual(results[0].album, "Album A") - self.assertEqual(results[-1].album, "album") + assert results[0].album == "Album A" + assert results[-1].album == "album" def test_flex_field_case_insensitive(self): config["sort_case_insensitive"] = True q = "flex1+" results = list(self.lib.items(q)) - self.assertEqual(results[0].flex1, "flex1") - self.assertEqual(results[1].flex1, "Flex1-0") + assert results[0].flex1 == "flex1" + assert results[1].flex1 == "Flex1-0" def test_flex_field_case_sensitive(self): config["sort_case_insensitive"] = False q = "flex1+" results = list(self.lib.items(q)) - self.assertEqual(results[0].flex1, "Flex1-0") - self.assertEqual(results[-1].flex1, "flex1") + assert results[0].flex1 == "Flex1-0" + assert results[-1].flex1 == "flex1" def test_case_sensitive_only_affects_text(self): config["sort_case_insensitive"] = True @@ -460,9 +460,9 @@ def test_case_sensitive_only_affects_text(self): # If the numerical values were sorted as strings, # then ['1', '10', '2'] would be valid. # print([r.track for r in results]) - self.assertEqual(results[0].track, 1) - self.assertEqual(results[1].track, 2) - self.assertEqual(results[-1].track, 10) + assert results[0].track == 1 + assert results[1].track == 2 + assert results[-1].track == 10 class NonExistingFieldTest(DummyDataTestCase): @@ -476,23 +476,23 @@ def test_non_existing_fields_not_fail(self): for q1 in qs: results1 = list(self.lib.items(q1)) for r1, r2 in zip(results0, results1): - self.assertEqual(r1.id, r2.id) + assert r1.id == r2.id def test_combined_non_existing_field_asc(self): all_results = list(self.lib.items("id+")) q = "foo+ id+" results = list(self.lib.items(q)) - self.assertEqual(len(all_results), len(results)) + assert len(all_results) == len(results) for r1, r2 in zip(all_results, results): - self.assertEqual(r1.id, r2.id) + assert r1.id == r2.id def test_combined_non_existing_field_desc(self): all_results = list(self.lib.items("id+")) q = "foo- id+" results = list(self.lib.items(q)) - self.assertEqual(len(all_results), len(results)) + assert len(all_results) == len(results) for r1, r2 in zip(all_results, results): - self.assertEqual(r1.id, r2.id) + assert r1.id == r2.id def test_field_present_in_some_items(self): """Test ordering by a field not present on all items.""" @@ -505,17 +505,11 @@ def test_field_present_in_some_items(self): items[2].store() results_asc = list(self.lib.items("foo+ id+")) - self.assertEqual( - [i.id for i in results_asc], - # items without field first - [ids[0], ids[3], ids[1], ids[2]], - ) + # items without field first + assert [i.id for i in results_asc] == [ids[0], ids[3], ids[1], ids[2]] results_desc = list(self.lib.items("foo- id+")) - self.assertEqual( - [i.id for i in results_desc], - # items without field last - [ids[2], ids[1], ids[0], ids[3]], - ) + # items without field last + assert [i.id for i in results_desc] == [ids[2], ids[1], ids[0], ids[3]] def test_negation_interaction(self): """Test the handling of negation and sorting together. @@ -526,7 +520,7 @@ def test_negation_interaction(self): query, sort = beets.library.parse_query_string( "-bar+", beets.library.Item ) - self.assertEqual(len(query.subqueries), 1) - self.assertTrue(isinstance(query.subqueries[0], dbcore.query.TrueQuery)) - self.assertTrue(isinstance(sort, dbcore.query.SlowFieldSort)) - self.assertEqual(sort.field, "-bar") + assert len(query.subqueries) == 1 + assert isinstance(query.subqueries[0], dbcore.query.TrueQuery) + assert isinstance(sort, dbcore.query.SlowFieldSort) + assert sort.field == "-bar" diff --git a/test/test_template.py b/test/test_template.py index 1fc35f7a31..23bf527a0e 100644 --- a/test/test_template.py +++ b/test/test_template.py @@ -49,194 +49,179 @@ def _normparse(text): class ParseTest(unittest.TestCase): def test_empty_string(self): - self.assertEqual(list(_normparse("")), []) + assert list(_normparse("")) == [] def _assert_symbol(self, obj, ident): """Assert that an object is a Symbol with the given identifier.""" - self.assertTrue( - isinstance(obj, functemplate.Symbol), "not a Symbol: %s" % repr(obj) - ) - self.assertEqual( - obj.ident, - ident, - "wrong identifier: %s vs. %s" % (repr(obj.ident), repr(ident)), - ) + assert isinstance(obj, functemplate.Symbol), f"not a Symbol: {obj}" + assert obj.ident == ident, f"wrong identifier: {obj.ident} vs. {ident}" def _assert_call(self, obj, ident, numargs): """Assert that an object is a Call with the given identifier and argument count. """ - self.assertTrue( - isinstance(obj, functemplate.Call), "not a Call: %s" % repr(obj) - ) - self.assertEqual( - obj.ident, - ident, - "wrong identifier: %s vs. %s" % (repr(obj.ident), repr(ident)), - ) - self.assertEqual( - len(obj.args), - numargs, - "wrong argument count in %s: %i vs. %i" - % (repr(obj.ident), len(obj.args), numargs), - ) + assert isinstance(obj, functemplate.Call), f"not a Call: {obj}" + assert obj.ident == ident, f"wrong identifier: {obj.ident} vs. {ident}" + assert ( + len(obj.args) == numargs + ), f"wrong argument count in {obj.ident}: {len(obj.args)} vs. {numargs}" def test_plain_text(self): - self.assertEqual(list(_normparse("hello world")), ["hello world"]) + assert list(_normparse("hello world")) == ["hello world"] def test_escaped_character_only(self): - self.assertEqual(list(_normparse("$$")), ["$"]) + assert list(_normparse("$$")) == ["$"] def test_escaped_character_in_text(self): - self.assertEqual(list(_normparse("a $$ b")), ["a $ b"]) + assert list(_normparse("a $$ b")) == ["a $ b"] def test_escaped_character_at_start(self): - self.assertEqual(list(_normparse("$$ hello")), ["$ hello"]) + assert list(_normparse("$$ hello")) == ["$ hello"] def test_escaped_character_at_end(self): - self.assertEqual(list(_normparse("hello $$")), ["hello $"]) + assert list(_normparse("hello $$")) == ["hello $"] def test_escaped_function_delim(self): - self.assertEqual(list(_normparse("a $% b")), ["a % b"]) + assert list(_normparse("a $% b")) == ["a % b"] def test_escaped_sep(self): - self.assertEqual(list(_normparse("a $, b")), ["a , b"]) + assert list(_normparse("a $, b")) == ["a , b"] def test_escaped_close_brace(self): - self.assertEqual(list(_normparse("a $} b")), ["a } b"]) + assert list(_normparse("a $} b")) == ["a } b"] def test_bare_value_delim_kept_intact(self): - self.assertEqual(list(_normparse("a $ b")), ["a $ b"]) + assert list(_normparse("a $ b")) == ["a $ b"] def test_bare_function_delim_kept_intact(self): - self.assertEqual(list(_normparse("a % b")), ["a % b"]) + assert list(_normparse("a % b")) == ["a % b"] def test_bare_opener_kept_intact(self): - self.assertEqual(list(_normparse("a { b")), ["a { b"]) + assert list(_normparse("a { b")) == ["a { b"] def test_bare_closer_kept_intact(self): - self.assertEqual(list(_normparse("a } b")), ["a } b"]) + assert list(_normparse("a } b")) == ["a } b"] def test_bare_sep_kept_intact(self): - self.assertEqual(list(_normparse("a , b")), ["a , b"]) + assert list(_normparse("a , b")) == ["a , b"] def test_symbol_alone(self): parts = list(_normparse("$foo")) - self.assertEqual(len(parts), 1) + assert len(parts) == 1 self._assert_symbol(parts[0], "foo") def test_symbol_in_text(self): parts = list(_normparse("hello $foo world")) - self.assertEqual(len(parts), 3) - self.assertEqual(parts[0], "hello ") + assert len(parts) == 3 + assert parts[0] == "hello " self._assert_symbol(parts[1], "foo") - self.assertEqual(parts[2], " world") + assert parts[2] == " world" def test_symbol_with_braces(self): parts = list(_normparse("hello${foo}world")) - self.assertEqual(len(parts), 3) - self.assertEqual(parts[0], "hello") + assert len(parts) == 3 + assert parts[0] == "hello" self._assert_symbol(parts[1], "foo") - self.assertEqual(parts[2], "world") + assert parts[2] == "world" def test_unclosed_braces_symbol(self): - self.assertEqual(list(_normparse("a ${ b")), ["a ${ b"]) + assert list(_normparse("a ${ b")) == ["a ${ b"] def test_empty_braces_symbol(self): - self.assertEqual(list(_normparse("a ${} b")), ["a ${} b"]) + assert list(_normparse("a ${} b")) == ["a ${} b"] def test_call_without_args_at_end(self): - self.assertEqual(list(_normparse("foo %bar")), ["foo %bar"]) + assert list(_normparse("foo %bar")) == ["foo %bar"] def test_call_without_args(self): - self.assertEqual(list(_normparse("foo %bar baz")), ["foo %bar baz"]) + assert list(_normparse("foo %bar baz")) == ["foo %bar baz"] def test_call_with_unclosed_args(self): - self.assertEqual(list(_normparse("foo %bar{ baz")), ["foo %bar{ baz"]) + assert list(_normparse("foo %bar{ baz")) == ["foo %bar{ baz"] def test_call_with_unclosed_multiple_args(self): - self.assertEqual( - list(_normparse("foo %bar{bar,bar baz")), ["foo %bar{bar,bar baz"] - ) + assert list(_normparse("foo %bar{bar,bar baz")) == [ + "foo %bar{bar,bar baz" + ] def test_call_empty_arg(self): parts = list(_normparse("%foo{}")) - self.assertEqual(len(parts), 1) + assert len(parts) == 1 self._assert_call(parts[0], "foo", 1) - self.assertEqual(list(_normexpr(parts[0].args[0])), []) + assert list(_normexpr(parts[0].args[0])) == [] def test_call_single_arg(self): parts = list(_normparse("%foo{bar}")) - self.assertEqual(len(parts), 1) + assert len(parts) == 1 self._assert_call(parts[0], "foo", 1) - self.assertEqual(list(_normexpr(parts[0].args[0])), ["bar"]) + assert list(_normexpr(parts[0].args[0])) == ["bar"] def test_call_two_args(self): parts = list(_normparse("%foo{bar,baz}")) - self.assertEqual(len(parts), 1) + assert len(parts) == 1 self._assert_call(parts[0], "foo", 2) - self.assertEqual(list(_normexpr(parts[0].args[0])), ["bar"]) - self.assertEqual(list(_normexpr(parts[0].args[1])), ["baz"]) + assert list(_normexpr(parts[0].args[0])) == ["bar"] + assert list(_normexpr(parts[0].args[1])) == ["baz"] def test_call_with_escaped_sep(self): parts = list(_normparse("%foo{bar$,baz}")) - self.assertEqual(len(parts), 1) + assert len(parts) == 1 self._assert_call(parts[0], "foo", 1) - self.assertEqual(list(_normexpr(parts[0].args[0])), ["bar,baz"]) + assert list(_normexpr(parts[0].args[0])) == ["bar,baz"] def test_call_with_escaped_close(self): parts = list(_normparse("%foo{bar$}baz}")) - self.assertEqual(len(parts), 1) + assert len(parts) == 1 self._assert_call(parts[0], "foo", 1) - self.assertEqual(list(_normexpr(parts[0].args[0])), ["bar}baz"]) + assert list(_normexpr(parts[0].args[0])) == ["bar}baz"] def test_call_with_symbol_argument(self): parts = list(_normparse("%foo{$bar,baz}")) - self.assertEqual(len(parts), 1) + assert len(parts) == 1 self._assert_call(parts[0], "foo", 2) arg_parts = list(_normexpr(parts[0].args[0])) - self.assertEqual(len(arg_parts), 1) + assert len(arg_parts) == 1 self._assert_symbol(arg_parts[0], "bar") - self.assertEqual(list(_normexpr(parts[0].args[1])), ["baz"]) + assert list(_normexpr(parts[0].args[1])) == ["baz"] def test_call_with_nested_call_argument(self): parts = list(_normparse("%foo{%bar{},baz}")) - self.assertEqual(len(parts), 1) + assert len(parts) == 1 self._assert_call(parts[0], "foo", 2) arg_parts = list(_normexpr(parts[0].args[0])) - self.assertEqual(len(arg_parts), 1) + assert len(arg_parts) == 1 self._assert_call(arg_parts[0], "bar", 1) - self.assertEqual(list(_normexpr(parts[0].args[1])), ["baz"]) + assert list(_normexpr(parts[0].args[1])) == ["baz"] def test_nested_call_with_argument(self): parts = list(_normparse("%foo{%bar{baz}}")) - self.assertEqual(len(parts), 1) + assert len(parts) == 1 self._assert_call(parts[0], "foo", 1) arg_parts = list(_normexpr(parts[0].args[0])) - self.assertEqual(len(arg_parts), 1) + assert len(arg_parts) == 1 self._assert_call(arg_parts[0], "bar", 1) - self.assertEqual(list(_normexpr(arg_parts[0].args[0])), ["baz"]) + assert list(_normexpr(arg_parts[0].args[0])) == ["baz"] def test_sep_before_call_two_args(self): parts = list(_normparse("hello, %foo{bar,baz}")) - self.assertEqual(len(parts), 2) - self.assertEqual(parts[0], "hello, ") + assert len(parts) == 2 + assert parts[0] == "hello, " self._assert_call(parts[1], "foo", 2) - self.assertEqual(list(_normexpr(parts[1].args[0])), ["bar"]) - self.assertEqual(list(_normexpr(parts[1].args[1])), ["baz"]) + assert list(_normexpr(parts[1].args[0])) == ["bar"] + assert list(_normexpr(parts[1].args[1])) == ["baz"] def test_sep_with_symbols(self): parts = list(_normparse("hello,$foo,$bar")) - self.assertEqual(len(parts), 4) - self.assertEqual(parts[0], "hello,") + assert len(parts) == 4 + assert parts[0] == "hello," self._assert_symbol(parts[1], "foo") - self.assertEqual(parts[2], ",") + assert parts[2] == "," self._assert_symbol(parts[3], "bar") def test_newline_at_end(self): parts = list(_normparse("foo\n")) - self.assertEqual(len(parts), 1) - self.assertEqual(parts[0], "foo\n") + assert len(parts) == 1 + assert parts[0] == "foo\n" class EvalTest(unittest.TestCase): @@ -252,41 +237,41 @@ def _eval(self, template): return functemplate.Template(template).substitute(values, functions) def test_plain_text(self): - self.assertEqual(self._eval("foo"), "foo") + assert self._eval("foo") == "foo" def test_subtitute_value(self): - self.assertEqual(self._eval("$foo"), "bar") + assert self._eval("$foo") == "bar" def test_subtitute_value_in_text(self): - self.assertEqual(self._eval("hello $foo world"), "hello bar world") + assert self._eval("hello $foo world") == "hello bar world" def test_not_subtitute_undefined_value(self): - self.assertEqual(self._eval("$bar"), "$bar") + assert self._eval("$bar") == "$bar" def test_function_call(self): - self.assertEqual(self._eval("%lower{FOO}"), "foo") + assert self._eval("%lower{FOO}") == "foo" def test_function_call_with_text(self): - self.assertEqual(self._eval("A %lower{FOO} B"), "A foo B") + assert self._eval("A %lower{FOO} B") == "A foo B" def test_nested_function_call(self): - self.assertEqual(self._eval("%lower{%lower{FOO}}"), "foo") + assert self._eval("%lower{%lower{FOO}}") == "foo" def test_symbol_in_argument(self): - self.assertEqual(self._eval("%lower{$baz}"), "bar") + assert self._eval("%lower{$baz}") == "bar" def test_function_call_exception(self): res = self._eval("%lower{a,b,c,d,e}") - self.assertTrue(isinstance(res, str)) + assert isinstance(res, str) def test_function_returning_integer(self): - self.assertEqual(self._eval("%len{foo}"), "3") + assert self._eval("%len{foo}") == "3" def test_not_subtitute_undefined_func(self): - self.assertEqual(self._eval("%bar{}"), "%bar{}") + assert self._eval("%bar{}") == "%bar{}" def test_not_subtitute_func_with_no_args(self): - self.assertEqual(self._eval("%lower"), "%lower") + assert self._eval("%lower") == "%lower" def test_function_call_with_empty_arg(self): - self.assertEqual(self._eval("%len{}"), "0") + assert self._eval("%len{}") == "0" diff --git a/test/test_ui.py b/test/test_ui.py index 7e2886e871..5423083e20 100644 --- a/test/test_ui.py +++ b/test/test_ui.py @@ -24,6 +24,7 @@ import unittest from unittest.mock import Mock, patch +import pytest from confuse import ConfigError from mediafile import MediaFile @@ -56,7 +57,7 @@ def _run_list(self, query="", album=False, path=False, fmt=""): def test_list_outputs_item(self): stdout = self._run_list() - self.assertIn("the title", stdout.getvalue()) + assert "the title" in stdout.getvalue() def test_list_unicode_query(self): self.item.title = "na\xefve" @@ -65,48 +66,46 @@ def test_list_unicode_query(self): stdout = self._run_list(["na\xefve"]) out = stdout.getvalue() - self.assertIn("na\xefve", out) + assert "na\xefve" in out def test_list_item_path(self): stdout = self._run_list(fmt="$path") - self.assertEqual(stdout.getvalue().strip(), "xxx/yyy") + assert stdout.getvalue().strip() == "xxx/yyy" def test_list_album_outputs_something(self): stdout = self._run_list(album=True) - self.assertGreater(len(stdout.getvalue()), 0) + assert len(stdout.getvalue()) > 0 def test_list_album_path(self): stdout = self._run_list(album=True, fmt="$path") - self.assertEqual(stdout.getvalue().strip(), "xxx") + assert stdout.getvalue().strip() == "xxx" def test_list_album_omits_title(self): stdout = self._run_list(album=True) - self.assertNotIn("the title", stdout.getvalue()) + assert "the title" not in stdout.getvalue() def test_list_uses_track_artist(self): stdout = self._run_list() - self.assertIn("the artist", stdout.getvalue()) - self.assertNotIn("the album artist", stdout.getvalue()) + assert "the artist" in stdout.getvalue() + assert "the album artist" not in stdout.getvalue() def test_list_album_uses_album_artist(self): stdout = self._run_list(album=True) - self.assertNotIn("the artist", stdout.getvalue()) - self.assertIn("the album artist", stdout.getvalue()) + assert "the artist" not in stdout.getvalue() + assert "the album artist" in stdout.getvalue() def test_list_item_format_artist(self): stdout = self._run_list(fmt="$artist") - self.assertIn("the artist", stdout.getvalue()) + assert "the artist" in stdout.getvalue() def test_list_item_format_multiple(self): stdout = self._run_list(fmt="$artist - $album - $year") - self.assertEqual( - "the artist - the album - 0001", stdout.getvalue().strip() - ) + assert "the artist - the album - 0001" == stdout.getvalue().strip() def test_list_album_format(self): stdout = self._run_list(album=True, fmt="$genre") - self.assertIn("the genre", stdout.getvalue()) - self.assertNotIn("the album", stdout.getvalue()) + assert "the genre" in stdout.getvalue() + assert "the album" not in stdout.getvalue() class RemoveTest(BeetsTestCase): @@ -125,26 +124,26 @@ def test_remove_items_no_delete(self): self.io.addinput("y") commands.remove_items(self.lib, "", False, False, False) items = self.lib.items() - self.assertEqual(len(list(items)), 0) + assert len(list(items)) == 0 self.assertExists(self.i.path) def test_remove_items_with_delete(self): self.io.addinput("y") commands.remove_items(self.lib, "", False, True, False) items = self.lib.items() - self.assertEqual(len(list(items)), 0) + assert len(list(items)) == 0 self.assertNotExists(self.i.path) def test_remove_items_with_force_no_delete(self): commands.remove_items(self.lib, "", False, False, True) items = self.lib.items() - self.assertEqual(len(list(items)), 0) + assert len(list(items)) == 0 self.assertExists(self.i.path) def test_remove_items_with_force_delete(self): commands.remove_items(self.lib, "", False, True, True) items = self.lib.items() - self.assertEqual(len(list(items)), 0) + assert len(list(items)) == 0 self.assertNotExists(self.i.path) def test_remove_items_select_with_delete(self): @@ -156,7 +155,7 @@ def test_remove_items_select_with_delete(self): self.io.addinput(s) commands.remove_items(self.lib, "", False, True, False) items = self.lib.items() - self.assertEqual(len(list(items)), 1) + assert len(list(items)) == 1 # There is probably no guarantee that the items are queried in any # spcecific order, thus just ensure that exactly one was removed. # To improve upon this, self.io would need to have the capability to @@ -164,7 +163,7 @@ def test_remove_items_select_with_delete(self): num_existing = 0 num_existing += 1 if os.path.exists(syspath(self.i.path)) else 0 num_existing += 1 if os.path.exists(syspath(i2.path)) else 0 - self.assertEqual(num_existing, 1) + assert num_existing == 1 def test_remove_albums_select_with_delete(self): a1 = self.add_album_fixture() @@ -172,18 +171,18 @@ def test_remove_albums_select_with_delete(self): path1 = a1.items()[0].path path2 = a2.items()[0].path items = self.lib.items() - self.assertEqual(len(list(items)), 3) + assert len(list(items)) == 3 for s in ("s", "y", "n"): self.io.addinput(s) commands.remove_items(self.lib, "", True, True, False) items = self.lib.items() - self.assertEqual(len(list(items)), 2) # incl. the item from setUp() + assert len(list(items)) == 2 # incl. the item from setUp() # See test_remove_items_select_with_delete() num_existing = 0 num_existing += 1 if os.path.exists(syspath(path1)) else 0 num_existing += 1 if os.path.exists(syspath(path2)) else 0 - self.assertEqual(num_existing, 1) + assert num_existing == 1 class ModifyTest(BeetsTestCase): @@ -204,50 +203,50 @@ def modify(self, *args): def test_modify_item(self): self.modify("title=newTitle") item = self.lib.items().get() - self.assertEqual(item.title, "newTitle") + assert item.title == "newTitle" def test_modify_item_abort(self): item = self.lib.items().get() title = item.title self.modify_inp("n", "title=newTitle") item = self.lib.items().get() - self.assertEqual(item.title, title) + assert item.title == title def test_modify_item_no_change(self): title = "Tracktitle" item = self.add_item_fixture(title=title) self.modify_inp("y", "title", f"title={title}") item = self.lib.items(title).get() - self.assertEqual(item.title, title) + assert item.title == title def test_modify_write_tags(self): self.modify("title=newTitle") item = self.lib.items().get() item.read() - self.assertEqual(item.title, "newTitle") + assert item.title == "newTitle" def test_modify_dont_write_tags(self): self.modify("--nowrite", "title=newTitle") item = self.lib.items().get() item.read() - self.assertNotEqual(item.title, "newTitle") + assert item.title != "newTitle" def test_move(self): self.modify("title=newTitle") item = self.lib.items().get() - self.assertIn(b"newTitle", item.path) + assert b"newTitle" in item.path def test_not_move(self): self.modify("--nomove", "title=newTitle") item = self.lib.items().get() - self.assertNotIn(b"newTitle", item.path) + assert b"newTitle" not in item.path def test_no_write_no_move(self): self.modify("--nomove", "--nowrite", "title=newTitle") item = self.lib.items().get() item.read() - self.assertNotIn(b"newTitle", item.path) - self.assertNotEqual(item.title, "newTitle") + assert b"newTitle" not in item.path + assert item.title != "newTitle" def test_update_mtime(self): item = self.item @@ -255,15 +254,15 @@ def test_update_mtime(self): self.modify("title=newTitle") item.load() - self.assertNotEqual(old_mtime, item.mtime) - self.assertEqual(item.current_mtime(), item.mtime) + assert old_mtime != item.mtime + assert item.current_mtime() == item.mtime def test_reset_mtime_with_no_write(self): item = self.item self.modify("--nowrite", "title=newTitle") item.load() - self.assertEqual(0, item.mtime) + assert 0 == item.mtime def test_selective_modify(self): title = "Tracktitle" @@ -279,8 +278,8 @@ def test_selective_modify(self): ) original_items = self.lib.items(f"artist:{original_artist}") new_items = self.lib.items(f"artist:{new_artist}") - self.assertEqual(len(list(original_items)), 3) - self.assertEqual(len(list(new_items)), 7) + assert len(list(original_items)) == 3 + assert len(list(new_items)) == 7 def test_modify_formatted(self): for i in range(0, 3): @@ -292,45 +291,45 @@ def test_modify_formatted(self): for item in items: orig_title = item.title item.load() - self.assertEqual(item.title, f"{orig_title} - append") + assert item.title == f"{orig_title} - append" # Album Tests def test_modify_album(self): self.modify("--album", "album=newAlbum") album = self.lib.albums().get() - self.assertEqual(album.album, "newAlbum") + assert album.album == "newAlbum" def test_modify_album_write_tags(self): self.modify("--album", "album=newAlbum") item = self.lib.items().get() item.read() - self.assertEqual(item.album, "newAlbum") + assert item.album == "newAlbum" def test_modify_album_dont_write_tags(self): self.modify("--album", "--nowrite", "album=newAlbum") item = self.lib.items().get() item.read() - self.assertEqual(item.album, "the album") + assert item.album == "the album" def test_album_move(self): self.modify("--album", "album=newAlbum") item = self.lib.items().get() item.read() - self.assertIn(b"newAlbum", item.path) + assert b"newAlbum" in item.path def test_album_not_move(self): self.modify("--nomove", "--album", "album=newAlbum") item = self.lib.items().get() item.read() - self.assertNotIn(b"newAlbum", item.path) + assert b"newAlbum" not in item.path def test_modify_album_formatted(self): item = self.lib.items().get() orig_album = item.album self.modify("--album", "album=${album} - append") item.load() - self.assertEqual(item.album, f"{orig_album} - append") + assert item.album == f"{orig_album} - append" # Misc @@ -338,12 +337,12 @@ def test_write_initial_key_tag(self): self.modify("initial_key=C#m") item = self.lib.items().get() mediafile = MediaFile(syspath(item.path)) - self.assertEqual(mediafile.initial_key, "C#m") + assert mediafile.initial_key == "C#m" def test_set_flexattr(self): self.modify("flexattr=testAttr") item = self.lib.items().get() - self.assertEqual(item.flexattr, "testAttr") + assert item.flexattr == "testAttr" def test_remove_flexattr(self): item = self.lib.items().get() @@ -352,7 +351,7 @@ def test_remove_flexattr(self): self.modify("flexattr!") item = self.lib.items().get() - self.assertNotIn("flexattr", item) + assert "flexattr" not in item @unittest.skip("not yet implemented") def test_delete_initial_key_tag(self): @@ -362,39 +361,39 @@ def test_delete_initial_key_tag(self): item.store() mediafile = MediaFile(syspath(item.path)) - self.assertEqual(mediafile.initial_key, "C#m") + assert mediafile.initial_key == "C#m" self.modify("initial_key!") mediafile = MediaFile(syspath(item.path)) - self.assertIsNone(mediafile.initial_key) + assert mediafile.initial_key is None def test_arg_parsing_colon_query(self): (query, mods, dels) = commands.modify_parse_args( ["title:oldTitle", "title=newTitle"] ) - self.assertEqual(query, ["title:oldTitle"]) - self.assertEqual(mods, {"title": "newTitle"}) + assert query == ["title:oldTitle"] + assert mods == {"title": "newTitle"} def test_arg_parsing_delete(self): (query, mods, dels) = commands.modify_parse_args( ["title:oldTitle", "title!"] ) - self.assertEqual(query, ["title:oldTitle"]) - self.assertEqual(dels, ["title"]) + assert query == ["title:oldTitle"] + assert dels == ["title"] def test_arg_parsing_query_with_exclaimation(self): (query, mods, dels) = commands.modify_parse_args( ["title:oldTitle!", "title=newTitle!"] ) - self.assertEqual(query, ["title:oldTitle!"]) - self.assertEqual(mods, {"title": "newTitle!"}) + assert query == ["title:oldTitle!"] + assert mods == {"title": "newTitle!"} def test_arg_parsing_equals_in_value(self): (query, mods, dels) = commands.modify_parse_args( ["title:foo=bar", "title=newTitle"] ) - self.assertEqual(query, ["title:foo=bar"]) - self.assertEqual(mods, {"title": "newTitle"}) + assert query == ["title:foo=bar"] + assert mods == {"title": "newTitle"} class WriteTest(BeetsTestCase): @@ -407,11 +406,11 @@ def test_update_mtime(self): item.store() item = self.lib.items().get() - self.assertEqual(item.mtime, 0) + assert item.mtime == 0 self.write_cmd() item = self.lib.items().get() - self.assertEqual(item.mtime, item.current_mtime()) + assert item.mtime == item.current_mtime() def test_non_metadata_field_unchanged(self): """Changing a non-"tag" field like `bitrate` and writing should @@ -427,7 +426,7 @@ def test_non_metadata_field_unchanged(self): output = self.write_cmd() - self.assertEqual(output, "") + assert output == "" def test_write_metadata_field(self): item = self.add_item_fixture() @@ -439,7 +438,7 @@ def test_write_metadata_field(self): output = self.write_cmd() - self.assertIn(f"{old_title} -> new title", output) + assert f"{old_title} -> new title" in output class MoveTest(BeetsTestCase): @@ -478,71 +477,71 @@ def _move( def test_move_item(self): self._move() self.i.load() - self.assertIn(b"libdir", self.i.path) + assert b"libdir" in self.i.path self.assertExists(self.i.path) self.assertNotExists(self.itempath) def test_copy_item(self): self._move(copy=True) self.i.load() - self.assertIn(b"libdir", self.i.path) + assert b"libdir" in self.i.path self.assertExists(self.i.path) self.assertExists(self.itempath) def test_move_album(self): self._move(album=True) self.i.load() - self.assertIn(b"libdir", self.i.path) + assert b"libdir" in self.i.path self.assertExists(self.i.path) self.assertNotExists(self.itempath) def test_copy_album(self): self._move(copy=True, album=True) self.i.load() - self.assertIn(b"libdir", self.i.path) + assert b"libdir" in self.i.path self.assertExists(self.i.path) self.assertExists(self.itempath) def test_move_item_custom_dir(self): self._move(dest=self.otherdir) self.i.load() - self.assertIn(b"testotherdir", self.i.path) + assert b"testotherdir" in self.i.path self.assertExists(self.i.path) self.assertNotExists(self.itempath) def test_move_album_custom_dir(self): self._move(dest=self.otherdir, album=True) self.i.load() - self.assertIn(b"testotherdir", self.i.path) + assert b"testotherdir" in self.i.path self.assertExists(self.i.path) self.assertNotExists(self.itempath) def test_pretend_move_item(self): self._move(dest=self.otherdir, pretend=True) self.i.load() - self.assertIn(b"srcfile", self.i.path) + assert b"srcfile" in self.i.path def test_pretend_move_album(self): self._move(album=True, pretend=True) self.i.load() - self.assertIn(b"srcfile", self.i.path) + assert b"srcfile" in self.i.path def test_export_item_custom_dir(self): self._move(dest=self.otherdir, export=True) self.i.load() - self.assertEqual(self.i.path, self.itempath) + assert self.i.path == self.itempath self.assertExists(self.otherdir) def test_export_album_custom_dir(self): self._move(dest=self.otherdir, album=True, export=True) self.i.load() - self.assertEqual(self.i.path, self.itempath) + assert self.i.path == self.itempath self.assertExists(self.otherdir) def test_pretend_export_item(self): self._move(dest=self.otherdir, pretend=True, export=True) self.i.load() - self.assertIn(b"srcfile", self.i.path) + assert b"srcfile" in self.i.path self.assertNotExists(self.otherdir) @@ -594,18 +593,18 @@ def _update( ) def test_delete_removes_item(self): - self.assertTrue(list(self.lib.items())) + assert list(self.lib.items()) util.remove(self.i.path) util.remove(self.i2.path) self._update() - self.assertFalse(list(self.lib.items())) + assert not list(self.lib.items()) def test_delete_removes_album(self): - self.assertTrue(self.lib.albums()) + assert self.lib.albums() util.remove(self.i.path) util.remove(self.i2.path) self._update() - self.assertFalse(self.lib.albums()) + assert not self.lib.albums() def test_delete_removes_album_art(self): artpath = self.album.artpath @@ -621,7 +620,7 @@ def test_modified_metadata_detected(self): mf.save() self._update() item = self.lib.items().get() - self.assertEqual(item.title, "differentTitle") + assert item.title == "differentTitle" def test_modified_metadata_moved(self): mf = MediaFile(syspath(self.i.path)) @@ -629,7 +628,7 @@ def test_modified_metadata_moved(self): mf.save() self._update(move=True) item = self.lib.items().get() - self.assertIn(b"differentTitle", item.path) + assert b"differentTitle" in item.path def test_modified_metadata_not_moved(self): mf = MediaFile(syspath(self.i.path)) @@ -637,7 +636,7 @@ def test_modified_metadata_not_moved(self): mf.save() self._update(move=False) item = self.lib.items().get() - self.assertNotIn(b"differentTitle", item.path) + assert b"differentTitle" not in item.path def test_selective_modified_metadata_moved(self): mf = MediaFile(syspath(self.i.path)) @@ -646,8 +645,8 @@ def test_selective_modified_metadata_moved(self): mf.save() self._update(move=True, fields=["title"]) item = self.lib.items().get() - self.assertIn(b"differentTitle", item.path) - self.assertNotEqual(item.genre, "differentGenre") + assert b"differentTitle" in item.path + assert item.genre != "differentGenre" def test_selective_modified_metadata_not_moved(self): mf = MediaFile(syspath(self.i.path)) @@ -656,8 +655,8 @@ def test_selective_modified_metadata_not_moved(self): mf.save() self._update(move=False, fields=["title"]) item = self.lib.items().get() - self.assertNotIn(b"differentTitle", item.path) - self.assertNotEqual(item.genre, "differentGenre") + assert b"differentTitle" not in item.path + assert item.genre != "differentGenre" def test_modified_album_metadata_moved(self): mf = MediaFile(syspath(self.i.path)) @@ -665,7 +664,7 @@ def test_modified_album_metadata_moved(self): mf.save() self._update(move=True) item = self.lib.items().get() - self.assertIn(b"differentAlbum", item.path) + assert b"differentAlbum" in item.path def test_modified_album_metadata_art_moved(self): artpath = self.album.artpath @@ -674,8 +673,8 @@ def test_modified_album_metadata_art_moved(self): mf.save() self._update(move=True) album = self.lib.albums()[0] - self.assertNotEqual(artpath, album.artpath) - self.assertIsNotNone(album.artpath) + assert artpath != album.artpath + assert album.artpath is not None def test_selective_modified_album_metadata_moved(self): mf = MediaFile(syspath(self.i.path)) @@ -684,8 +683,8 @@ def test_selective_modified_album_metadata_moved(self): mf.save() self._update(move=True, fields=["album"]) item = self.lib.items().get() - self.assertIn(b"differentAlbum", item.path) - self.assertNotEqual(item.genre, "differentGenre") + assert b"differentAlbum" in item.path + assert item.genre != "differentGenre" def test_selective_modified_album_metadata_not_moved(self): mf = MediaFile(syspath(self.i.path)) @@ -694,8 +693,8 @@ def test_selective_modified_album_metadata_not_moved(self): mf.save() self._update(move=True, fields=["genre"]) item = self.lib.items().get() - self.assertNotIn(b"differentAlbum", item.path) - self.assertEqual(item.genre, "differentGenre") + assert b"differentAlbum" not in item.path + assert item.genre == "differentGenre" def test_mtime_match_skips_update(self): mf = MediaFile(syspath(self.i.path)) @@ -708,7 +707,7 @@ def test_mtime_match_skips_update(self): self._update(reset_mtime=False) item = self.lib.items().get() - self.assertEqual(item.title, "full") + assert item.title == "full" def test_multivalued_albumtype_roundtrip(self): # https://github.com/beetbox/beets/issues/4528 @@ -726,14 +725,14 @@ def test_multivalued_albumtype_roundtrip(self): album.try_sync(write=True, move=False) album.load() - self.assertEqual(album.albumtype, correct_albumtype) - self.assertEqual(album.albumtypes, correct_albumtypes) + assert album.albumtype == correct_albumtype + assert album.albumtypes == correct_albumtypes self._update() album.load() - self.assertEqual(album.albumtype, correct_albumtype) - self.assertEqual(album.albumtypes, correct_albumtypes) + assert album.albumtype == correct_albumtype + assert album.albumtypes == correct_albumtypes def test_modified_metadata_excluded(self): mf = MediaFile(syspath(self.i.path)) @@ -741,7 +740,7 @@ def test_modified_metadata_excluded(self): mf.save() self._update(exclude_fields=["lyrics"]) item = self.lib.items().get() - self.assertNotEqual(item.lyrics, "new lyrics") + assert item.lyrics != "new lyrics" class PrintTest(BeetsTestCase): @@ -787,7 +786,8 @@ class ImportTest(BeetsTestCase): def test_quiet_timid_disallowed(self): config["import"]["quiet"] = True config["import"]["timid"] = True - self.assertRaises(ui.UserError, commands.import_files, None, [], None) + with pytest.raises(ui.UserError): + commands.import_files(None, [], None) def test_parse_paths_from_logfile(self): if os.path.__name__ == "ntpath": @@ -821,7 +821,7 @@ def test_parse_paths_from_logfile(self): with open(logfile, mode="w") as fp: fp.write(logfile_content) actual_paths = list(commands._paths_from_logfile(logfile)) - self.assertEqual(actual_paths, expected_paths) + assert actual_paths == expected_paths @_common.slow_test() @@ -906,8 +906,8 @@ def test_paths_section_respected(self): self.run_command("test", lib=None) key, template = self.test_cmd.lib.path_formats[0] - self.assertEqual(key, "x") - self.assertEqual(template.original, "y") + assert key == "x" + assert template.original == "y" def test_default_paths_preserved(self): default_formats = ui.get_path_formats() @@ -917,15 +917,15 @@ def test_default_paths_preserved(self): config.write("paths: {x: y}") self.run_command("test", lib=None) key, template = self.test_cmd.lib.path_formats[0] - self.assertEqual(key, "x") - self.assertEqual(template.original, "y") - self.assertEqual(self.test_cmd.lib.path_formats[1:], default_formats) + assert key == "x" + assert template.original == "y" + assert self.test_cmd.lib.path_formats[1:] == default_formats def test_nonexistant_db(self): with self.write_config_file() as config: config.write("library: /xxx/yyy/not/a/real/path") - with self.assertRaises(ui.UserError): + with pytest.raises(ui.UserError): self.run_command("test", lib=None) def test_user_config_file(self): @@ -933,7 +933,7 @@ def test_user_config_file(self): file.write("anoption: value") self.run_command("test", lib=None) - self.assertEqual(config["anoption"].get(), "value") + assert config["anoption"].get() == "value" def test_replacements_parsed(self): with self.write_config_file() as config: @@ -942,7 +942,7 @@ def test_replacements_parsed(self): self.run_command("test", lib=None) replacements = self.test_cmd.lib.replacements repls = [(p.pattern, s) for p, s in replacements] # Compare patterns. - self.assertEqual(repls, [("[xy]", "z")]) + assert repls == [("[xy]", "z")] def test_multiple_replacements_parsed(self): with self.write_config_file() as config: @@ -950,20 +950,14 @@ def test_multiple_replacements_parsed(self): self.run_command("test", lib=None) replacements = self.test_cmd.lib.replacements repls = [(p.pattern, s) for p, s in replacements] - self.assertEqual( - repls, - [ - ("[xy]", "z"), - ("foo", "bar"), - ], - ) + assert repls == [("[xy]", "z"), ("foo", "bar")] def test_cli_config_option(self): config_path = os.path.join(self.temp_dir, b"config.yaml") with open(config_path, "w") as file: file.write("anoption: value") self.run_command("--config", config_path, "test", lib=None) - self.assertEqual(config["anoption"].get(), "value") + assert config["anoption"].get() == "value" def test_cli_config_file_overwrites_user_defaults(self): with open(self.user_config_path, "w") as file: @@ -973,7 +967,7 @@ def test_cli_config_file_overwrites_user_defaults(self): with open(cli_config_path, "w") as file: file.write("anoption: cli overwrite") self.run_command("--config", cli_config_path, "test", lib=None) - self.assertEqual(config["anoption"].get(), "cli overwrite") + assert config["anoption"].get() == "cli overwrite" def test_cli_config_file_overwrites_beetsdir_defaults(self): os.environ["BEETSDIR"] = os.fsdecode(self.beetsdir) @@ -985,7 +979,7 @@ def test_cli_config_file_overwrites_beetsdir_defaults(self): with open(cli_config_path, "w") as file: file.write("anoption: cli overwrite") self.run_command("--config", cli_config_path, "test", lib=None) - self.assertEqual(config["anoption"].get(), "cli overwrite") + assert config["anoption"].get() == "cli overwrite" # @unittest.skip('Difficult to implement with optparse') # def test_multiple_cli_config_files(self): @@ -1000,8 +994,8 @@ def test_cli_config_file_overwrites_beetsdir_defaults(self): # # self.run_command('--config', cli_config_path_1, # '--config', cli_config_path_2, 'test', lib=None) - # self.assertEqual(config['first'].get(), 'value') - # self.assertEqual(config['second'].get(), 'value') + # assert config['first'].get() == 'value' + # assert config['second'].get() == 'value' # # @unittest.skip('Difficult to implement with optparse') # def test_multiple_cli_config_overwrite(self): @@ -1017,7 +1011,7 @@ def test_cli_config_file_overwrites_beetsdir_defaults(self): # # self.run_command('--config', cli_config_path, # '--config', cli_overwrite_config_path, 'test') - # self.assertEqual(config['anoption'].get(), 'cli overwrite') + # assert config['anoption'].get() == 'cli overwrite' # FIXME: fails on windows @unittest.skipIf(sys.platform == "win32", "win32") @@ -1070,7 +1064,7 @@ def test_cli_config_file_loads_plugin_commands(self): file.write("plugins: test") self.run_command("--config", cli_config_path, "plugin", lib=None) - self.assertTrue(plugins.find_plugins()[0].is_test_plugin) + assert plugins.find_plugins()[0].is_test_plugin self.unload_plugins() def test_beetsdir_config(self): @@ -1081,13 +1075,14 @@ def test_beetsdir_config(self): file.write("anoption: overwrite") config.read() - self.assertEqual(config["anoption"].get(), "overwrite") + assert config["anoption"].get() == "overwrite" def test_beetsdir_points_to_file_error(self): beetsdir = os.path.join(self.temp_dir, b"beetsfile") open(beetsdir, "a").close() os.environ["BEETSDIR"] = os.fsdecode(beetsdir) - self.assertRaises(ConfigError, self.run_command, "test") + with pytest.raises(ConfigError): + self.run_command("test") def test_beetsdir_config_does_not_load_default_user_config(self): os.environ["BEETSDIR"] = os.fsdecode(self.beetsdir) @@ -1096,7 +1091,7 @@ def test_beetsdir_config_does_not_load_default_user_config(self): file.write("anoption: value") config.read() - self.assertFalse(config["anoption"].exists()) + assert not config["anoption"].exists() def test_default_config_paths_resolve_relative_to_beetsdir(self): os.environ["BEETSDIR"] = os.fsdecode(self.beetsdir) @@ -1145,41 +1140,41 @@ def _show(self, **kwargs): def test_identical(self): change, out = self._show() - self.assertFalse(change) - self.assertEqual(out, "") + assert not change + assert out == "" def test_string_fixed_field_change(self): self.b.title = "x" change, out = self._show() - self.assertTrue(change) - self.assertIn("title", out) + assert change + assert "title" in out def test_int_fixed_field_change(self): self.b.track = 9 change, out = self._show() - self.assertTrue(change) - self.assertIn("track", out) + assert change + assert "track" in out def test_floats_close_to_identical(self): self.a.length = 1.00001 self.b.length = 1.00005 change, out = self._show() - self.assertFalse(change) - self.assertEqual(out, "") + assert not change + assert out == "" def test_floats_different(self): self.a.length = 1.00001 self.b.length = 2.00001 change, out = self._show() - self.assertTrue(change) - self.assertIn("length", out) + assert change + assert "length" in out def test_both_values_shown(self): self.a.title = "foo" self.b.title = "bar" change, out = self._show() - self.assertIn("foo", out) - self.assertIn("bar", out) + assert "foo" in out + assert "bar" in out class ShowChangeTest(BeetsTestCase): @@ -1228,64 +1223,64 @@ def _show_change( def test_null_change(self): msg = self._show_change() - self.assertIn("match (90.0%)", msg) - self.assertIn("album, artist", msg) + assert "match (90.0%)" in msg + assert "album, artist" in msg def test_album_data_change(self): msg = self._show_change( cur_artist="another artist", cur_album="another album" ) - self.assertIn("another artist -> the artist", msg) - self.assertIn("another album -> the album", msg) + assert "another artist -> the artist" in msg + assert "another album -> the album" in msg def test_item_data_change(self): self.items[0].title = "different" msg = self._show_change() - self.assertTrue("different" in msg and "the title" in msg) + assert "different" in msg and "the title" in msg def test_item_data_change_with_unicode(self): self.items[0].title = "caf\xe9" msg = self._show_change() - self.assertTrue("caf\xe9" in msg and "the title" in msg) + assert "caf\xe9" in msg and "the title" in msg def test_album_data_change_with_unicode(self): msg = self._show_change(cur_artist="caf\xe9", cur_album="another album") - self.assertTrue("caf\xe9" in msg and "the artist" in msg) + assert "caf\xe9" in msg and "the artist" in msg def test_item_data_change_title_missing(self): self.items[0].title = "" msg = re.sub(r" +", " ", self._show_change()) - self.assertTrue("file.mp3" in msg and "the title" in msg) + assert "file.mp3" in msg and "the title" in msg def test_item_data_change_title_missing_with_unicode_filename(self): self.items[0].title = "" self.items[0].path = "/path/to/caf\xe9.mp3".encode() msg = re.sub(r" +", " ", self._show_change()) - self.assertTrue("caf\xe9.mp3" in msg or "caf.mp3" in msg) + assert "caf\xe9.mp3" in msg or "caf.mp3" in msg def test_colorize(self): - self.assertEqual("test", ui.uncolorize("test")) + assert "test" == ui.uncolorize("test") txt = ui.uncolorize("\x1b[31mtest\x1b[39;49;00m") - self.assertEqual("test", txt) + assert "test" == txt txt = ui.uncolorize("\x1b[31mtest\x1b[39;49;00m test") - self.assertEqual("test test", txt) + assert "test test" == txt txt = ui.uncolorize("\x1b[31mtest\x1b[39;49;00mtest") - self.assertEqual("testtest", txt) + assert "testtest" == txt txt = ui.uncolorize("test \x1b[31mtest\x1b[39;49;00m test") - self.assertEqual("test test test", txt) + assert "test test test" == txt def test_color_split(self): exp = ("test", "") res = ui.color_split("test", 5) - self.assertEqual(exp, res) + assert exp == res exp = ("\x1b[31mtes\x1b[39;49;00m", "\x1b[31mt\x1b[39;49;00m") res = ui.color_split("\x1b[31mtest\x1b[39;49;00m", 3) - self.assertEqual(exp, res) + assert exp == res def test_split_into_lines(self): # Test uncolored text txt = ui.split_into_lines("test test test", [5, 5, 5]) - self.assertEqual(txt, ["test", "test", "test"]) + assert txt == ["test", "test", "test"] # Test multiple colored texts colored_text = "\x1b[31mtest \x1b[39;49;00m" * 3 split_txt = [ @@ -1294,18 +1289,18 @@ def test_split_into_lines(self): "\x1b[31mtest\x1b[39;49;00m", ] txt = ui.split_into_lines(colored_text, [5, 5, 5]) - self.assertEqual(txt, split_txt) + assert txt == split_txt # Test single color, multi space text colored_text = "\x1b[31m test test test \x1b[39;49;00m" txt = ui.split_into_lines(colored_text, [5, 5, 5]) - self.assertEqual(txt, split_txt) + assert txt == split_txt # Test single color, different spacing colored_text = "\x1b[31mtest\x1b[39;49;00mtest test test" # ToDo: fix color_len to handle mid-text color escapes, and thus # split colored texts over newlines (potentially with dashes?) split_txt = ["\x1b[31mtest\x1b[39;49;00mt", "est", "test", "test"] txt = ui.split_into_lines(colored_text, [5, 5, 5]) - self.assertEqual(txt, split_txt) + assert txt == split_txt def test_album_data_change_wrap_newline(self): # Patch ui.term_width to force wrapping @@ -1317,9 +1312,9 @@ def test_album_data_change_wrap_newline(self): cur_artist=long_name, cur_album="another album" ) # _common.log.info("Message:{}".format(msg)) - self.assertIn("artist: another artist", msg) - self.assertIn(" -> the artist", msg) - self.assertNotIn("another album -> the album", msg) + assert "artist: another artist" in msg + assert " -> the artist" in msg + assert "another album -> the album" not in msg def test_item_data_change_wrap_column(self): # Patch ui.term_width to force wrapping @@ -1329,7 +1324,7 @@ def test_item_data_change_wrap_column(self): long_title = "a track with a" + (" very" * 10) + " long name" self.items[0].title = long_title msg = self._show_change() - self.assertIn("(#1) a track (1:00) -> (#1) the title (0:00)", msg) + assert "(#1) a track (1:00) -> (#1) the title (0:00)" in msg def test_item_data_change_wrap_newline(self): # Patch ui.term_width to force wrapping @@ -1338,8 +1333,8 @@ def test_item_data_change_wrap_newline(self): long_title = "a track with a" + (" very" * 10) + " long name" self.items[0].title = long_title msg = self._show_change() - self.assertIn("(#1) a track with", msg) - self.assertIn(" -> (#1) the title (0:00)", msg) + assert "(#1) a track with" in msg + assert " -> (#1) the title (0:00)" in msg @patch("beets.library.Item.try_filesize", Mock(return_value=987)) @@ -1354,30 +1349,30 @@ def setUp(self): def test_summarize_item(self): summary = commands.summarize_items([], True) - self.assertEqual(summary, "") + assert summary == "" summary = commands.summarize_items([self.item], True) - self.assertEqual(summary, "F, 4kbps, 10:54, 987.0 B") + assert summary == "F, 4kbps, 10:54, 987.0 B" def test_summarize_items(self): summary = commands.summarize_items([], False) - self.assertEqual(summary, "0 items") + assert summary == "0 items" summary = commands.summarize_items([self.item], False) - self.assertEqual(summary, "1 items, F, 4kbps, 10:54, 987.0 B") + assert summary == "1 items, F, 4kbps, 10:54, 987.0 B" # make a copy of self.item i2 = self.item.copy() summary = commands.summarize_items([self.item, i2], False) - self.assertEqual(summary, "2 items, F, 4kbps, 21:48, 1.9 KiB") + assert summary == "2 items, F, 4kbps, 21:48, 1.9 KiB" i2.format = "G" summary = commands.summarize_items([self.item, i2], False) - self.assertEqual(summary, "2 items, F 1, G 1, 4kbps, 21:48, 1.9 KiB") + assert summary == "2 items, F 1, G 1, 4kbps, 21:48, 1.9 KiB" summary = commands.summarize_items([self.item, i2, i2], False) - self.assertEqual(summary, "3 items, G 2, F 1, 4kbps, 32:42, 2.9 KiB") + assert summary == "3 items, G 2, F 1, 4kbps, 32:42, 2.9 KiB" class PathFormatTest(BeetsTestCase): @@ -1387,9 +1382,9 @@ def test_custom_paths_prepend(self): config["paths"] = {"foo": "bar"} pf = ui.get_path_formats() key, tmpl = pf[0] - self.assertEqual(key, "foo") - self.assertEqual(tmpl.original, "bar") - self.assertEqual(pf[1:], default_formats) + assert key == "foo" + assert tmpl.original == "bar" + assert pf[1:] == default_formats @_common.slow_test() @@ -1440,10 +1435,10 @@ def test_completion(self): with open(test_script_name, "rb") as test_script_file: tester.stdin.writelines(test_script_file) out, err = tester.communicate() - self.assertFalse( - tester.returncode != 0 or out != b"completion tests passed\n", - f"test/test_completion.sh did not execute properly. " - f'Output:{out.decode("utf-8")}', + assert tester.returncode == 0 + assert out == b"completion tests passed\n", ( + "test/test_completion.sh did not execute properly. " + f'Output:{out.decode("utf-8")}' ) @@ -1461,122 +1456,122 @@ def setUp(self): def test_base(self): l = self.run_with_output("ls") - self.assertEqual(l, "the artist - the album - the title\n") + assert l == "the artist - the album - the title\n" l = self.run_with_output("ls", "-a") - self.assertEqual(l, "the album artist - the album\n") + assert l == "the album artist - the album\n" def test_path_option(self): l = self.run_with_output("ls", "-p") - self.assertEqual(l, "xxx/yyy\n") + assert l == "xxx/yyy\n" l = self.run_with_output("ls", "-a", "-p") - self.assertEqual(l, "xxx\n") + assert l == "xxx\n" def test_format_option(self): l = self.run_with_output("ls", "-f", "$artist") - self.assertEqual(l, "the artist\n") + assert l == "the artist\n" l = self.run_with_output("ls", "-a", "-f", "$albumartist") - self.assertEqual(l, "the album artist\n") + assert l == "the album artist\n" def test_format_option_unicode(self): l = self.run_with_output( b"ls", b"-f", "caf\xe9".encode(util.arg_encoding()) ) - self.assertEqual(l, "caf\xe9\n") + assert l == "caf\xe9\n" def test_root_format_option(self): l = self.run_with_output( "--format-item", "$artist", "--format-album", "foo", "ls" ) - self.assertEqual(l, "the artist\n") + assert l == "the artist\n" l = self.run_with_output( "--format-item", "foo", "--format-album", "$albumartist", "ls", "-a" ) - self.assertEqual(l, "the album artist\n") + assert l == "the album artist\n" def test_help(self): l = self.run_with_output("help") - self.assertIn("Usage:", l) + assert "Usage:" in l l = self.run_with_output("help", "list") - self.assertIn("Usage:", l) + assert "Usage:" in l - with self.assertRaises(ui.UserError): + with pytest.raises(ui.UserError): self.run_command("help", "this.is.not.a.real.command") def test_stats(self): l = self.run_with_output("stats") - self.assertIn("Approximate total size:", l) + assert "Approximate total size:" in l # # Need to have more realistic library setup for this to work # l = self.run_with_output('stats', '-e') - # self.assertIn('Total size:', l) + # assert 'Total size:' in l def test_version(self): l = self.run_with_output("version") - self.assertIn("Python version", l) - self.assertIn("no plugins loaded", l) + assert "Python version" in l + assert "no plugins loaded" in l # # Need to have plugin loaded # l = self.run_with_output('version') - # self.assertIn('plugins: ', l) + # assert 'plugins: ' in l class CommonOptionsParserTest(BeetsTestCase): def test_album_option(self): parser = ui.CommonOptionsParser() - self.assertFalse(parser._album_flags) + assert not parser._album_flags parser.add_album_option() - self.assertTrue(bool(parser._album_flags)) + assert bool(parser._album_flags) - self.assertEqual(parser.parse_args([]), ({"album": None}, [])) - self.assertEqual(parser.parse_args(["-a"]), ({"album": True}, [])) - self.assertEqual(parser.parse_args(["--album"]), ({"album": True}, [])) + assert parser.parse_args([]) == ({"album": None}, []) + assert parser.parse_args(["-a"]) == ({"album": True}, []) + assert parser.parse_args(["--album"]) == ({"album": True}, []) def test_path_option(self): parser = ui.CommonOptionsParser() parser.add_path_option() - self.assertFalse(parser._album_flags) + assert not parser._album_flags config["format_item"].set("$foo") - self.assertEqual(parser.parse_args([]), ({"path": None}, [])) - self.assertEqual(config["format_item"].as_str(), "$foo") + assert parser.parse_args([]) == ({"path": None}, []) + assert config["format_item"].as_str() == "$foo" - self.assertEqual( - parser.parse_args(["-p"]), ({"path": True, "format": "$path"}, []) + assert parser.parse_args(["-p"]) == ( + {"path": True, "format": "$path"}, + [], ) - self.assertEqual( - parser.parse_args(["--path"]), - ({"path": True, "format": "$path"}, []), + assert parser.parse_args(["--path"]) == ( + {"path": True, "format": "$path"}, + [], ) - self.assertEqual(config["format_item"].as_str(), "$path") - self.assertEqual(config["format_album"].as_str(), "$path") + assert config["format_item"].as_str() == "$path" + assert config["format_album"].as_str() == "$path" def test_format_option(self): parser = ui.CommonOptionsParser() parser.add_format_option() - self.assertFalse(parser._album_flags) + assert not parser._album_flags config["format_item"].set("$foo") - self.assertEqual(parser.parse_args([]), ({"format": None}, [])) - self.assertEqual(config["format_item"].as_str(), "$foo") + assert parser.parse_args([]) == ({"format": None}, []) + assert config["format_item"].as_str() == "$foo" - self.assertEqual( - parser.parse_args(["-f", "$bar"]), ({"format": "$bar"}, []) - ) - self.assertEqual( - parser.parse_args(["--format", "$baz"]), ({"format": "$baz"}, []) + assert parser.parse_args(["-f", "$bar"]) == ({"format": "$bar"}, []) + assert parser.parse_args(["--format", "$baz"]) == ( + {"format": "$baz"}, + [], ) - self.assertEqual(config["format_item"].as_str(), "$baz") - self.assertEqual(config["format_album"].as_str(), "$baz") + assert config["format_item"].as_str() == "$baz" + assert config["format_album"].as_str() == "$baz" def test_format_option_with_target(self): - with self.assertRaises(KeyError): + with pytest.raises(KeyError): ui.CommonOptionsParser().add_format_option(target="thingy") parser = ui.CommonOptionsParser() @@ -1585,12 +1580,10 @@ def test_format_option_with_target(self): config["format_item"].set("$item") config["format_album"].set("$album") - self.assertEqual( - parser.parse_args(["-f", "$bar"]), ({"format": "$bar"}, []) - ) + assert parser.parse_args(["-f", "$bar"]) == ({"format": "$bar"}, []) - self.assertEqual(config["format_item"].as_str(), "$bar") - self.assertEqual(config["format_album"].as_str(), "$album") + assert config["format_item"].as_str() == "$bar" + assert config["format_album"].as_str() == "$album" def test_format_option_with_album(self): parser = ui.CommonOptionsParser() @@ -1601,22 +1594,22 @@ def test_format_option_with_album(self): config["format_album"].set("$album") parser.parse_args(["-f", "$bar"]) - self.assertEqual(config["format_item"].as_str(), "$bar") - self.assertEqual(config["format_album"].as_str(), "$album") + assert config["format_item"].as_str() == "$bar" + assert config["format_album"].as_str() == "$album" parser.parse_args(["-a", "-f", "$foo"]) - self.assertEqual(config["format_item"].as_str(), "$bar") - self.assertEqual(config["format_album"].as_str(), "$foo") + assert config["format_item"].as_str() == "$bar" + assert config["format_album"].as_str() == "$foo" parser.parse_args(["-f", "$foo2", "-a"]) - self.assertEqual(config["format_album"].as_str(), "$foo2") + assert config["format_album"].as_str() == "$foo2" def test_add_all_common_options(self): parser = ui.CommonOptionsParser() parser.add_all_common_options() - self.assertEqual( - parser.parse_args([]), - ({"album": None, "path": None, "format": None}, []), + assert parser.parse_args([]) == ( + {"album": None, "path": None, "format": None}, + [], ) @@ -1627,18 +1620,18 @@ class EncodingTest(BeetsTestCase): def out_encoding_overridden(self): config["terminal_encoding"] = "fake_encoding" - self.assertEqual(ui._out_encoding(), "fake_encoding") + assert ui._out_encoding() == "fake_encoding" def in_encoding_overridden(self): config["terminal_encoding"] = "fake_encoding" - self.assertEqual(ui._in_encoding(), "fake_encoding") + assert ui._in_encoding() == "fake_encoding" def out_encoding_default_utf8(self): with patch("sys.stdout") as stdout: stdout.encoding = None - self.assertEqual(ui._out_encoding(), "utf-8") + assert ui._out_encoding() == "utf-8" def in_encoding_default_utf8(self): with patch("sys.stdin") as stdin: stdin.encoding = None - self.assertEqual(ui._in_encoding(), "utf-8") + assert ui._in_encoding() == "utf-8" diff --git a/test/test_ui_commands.py b/test/test_ui_commands.py index b88616beec..c8a39dc694 100644 --- a/test/test_ui_commands.py +++ b/test/test_ui_commands.py @@ -19,6 +19,8 @@ import os import shutil +import pytest + from beets import library, ui from beets.test import _common from beets.test.helper import BeetsTestCase, ItemInDBTestCase @@ -45,15 +47,15 @@ def check_do_query( self, num_items, num_albums, q=(), album=False, also_items=True ): items, albums = commands._do_query(self.lib, q, album, also_items) - self.assertEqual(len(items), num_items) - self.assertEqual(len(albums), num_albums) + assert len(items) == num_items + assert len(albums) == num_albums def test_query_empty(self): - with self.assertRaises(ui.UserError): + with pytest.raises(ui.UserError): commands._do_query(self.lib, (), False) def test_query_empty_album(self): - with self.assertRaises(ui.UserError): + with pytest.raises(ui.UserError): commands._do_query(self.lib, (), True) def test_query_item(self): @@ -101,5 +103,5 @@ def test_fields_func(self): self.remove_keys(items, output) self.remove_keys(albums, output) - self.assertEqual(len(items), 0) - self.assertEqual(len(albums), 0) + assert len(items) == 0 + assert len(albums) == 0 diff --git a/test/test_ui_init.py b/test/test_ui_init.py index c11bc5b82b..29ce36a613 100644 --- a/test/test_ui_init.py +++ b/test/test_ui_init.py @@ -44,14 +44,14 @@ def test_input_select_objects(self): items = ui.input_select_objects( "Prompt", full_items, self._print_helper ) - self.assertEqual(items, []) + assert items == [] # Test yes self.io.addinput("y") items = ui.input_select_objects( "Prompt", full_items, self._print_helper ) - self.assertEqual(items, full_items) + assert items == full_items # Test selective 1 self.io.addinput("s") @@ -63,7 +63,7 @@ def test_input_select_objects(self): items = ui.input_select_objects( "Prompt", full_items, self._print_helper ) - self.assertEqual(items, ["2", "4"]) + assert items == ["2", "4"] # Test selective 2 self.io.addinput("s") @@ -75,7 +75,7 @@ def test_input_select_objects(self): items = ui.input_select_objects( "Prompt", full_items, lambda s: self._print_helper2(s, "Prefix") ) - self.assertEqual(items, ["1", "2", "4"]) + assert items == ["1", "2", "4"] # Test selective 3 self.io.addinput("s") @@ -86,7 +86,7 @@ def test_input_select_objects(self): items = ui.input_select_objects( "Prompt", full_items, self._print_helper ) - self.assertEqual(items, ["1", "3"]) + assert items == ["1", "3"] class InitTest(ItemInDBTestCase): @@ -106,7 +106,7 @@ def test_human_bytes(self): (pow(2, 100), "big"), ] for i, h in tests: - self.assertEqual(h, ui.human_bytes(i)) + assert h == ui.human_bytes(i) def test_human_seconds(self): tests = [ @@ -122,7 +122,7 @@ def test_human_seconds(self): (314496000, "1.0 decades"), ] for i, h in tests: - self.assertEqual(h, ui.human_seconds(i)) + assert h == ui.human_seconds(i) class ParentalDirCreation(BeetsTestCase): diff --git a/test/test_util.py b/test/test_util.py index 82ee94b377..c719bafa61 100644 --- a/test/test_util.py +++ b/test/test_util.py @@ -22,6 +22,8 @@ import unittest from unittest.mock import Mock, patch +import pytest + from beets import util from beets.test import _common from beets.test.helper import BeetsTestCase @@ -30,13 +32,13 @@ class UtilTest(unittest.TestCase): def test_open_anything(self): with _common.system_mock("Windows"): - self.assertEqual(util.open_anything(), "start") + assert util.open_anything() == "start" with _common.system_mock("Darwin"): - self.assertEqual(util.open_anything(), "open") + assert util.open_anything() == "open" with _common.system_mock("Tagada"): - self.assertEqual(util.open_anything(), "xdg-open") + assert util.open_anything() == "xdg-open" @patch("os.execlp") @patch("beets.util.open_anything") @@ -52,73 +54,56 @@ def test_interactive_open(self, mock_open, mock_execlp): def test_sanitize_unix_replaces_leading_dot(self): with _common.platform_posix(): p = util.sanitize_path("one/.two/three") - self.assertNotIn(".", p) + assert "." not in p def test_sanitize_windows_replaces_trailing_dot(self): with _common.platform_windows(): p = util.sanitize_path("one/two./three") - self.assertNotIn(".", p) + assert "." not in p def test_sanitize_windows_replaces_illegal_chars(self): with _common.platform_windows(): p = util.sanitize_path(':*?"<>|') - self.assertNotIn(":", p) - self.assertNotIn("*", p) - self.assertNotIn("?", p) - self.assertNotIn('"', p) - self.assertNotIn("<", p) - self.assertNotIn(">", p) - self.assertNotIn("|", p) + assert ":" not in p + assert "*" not in p + assert "?" not in p + assert '"' not in p + assert "<" not in p + assert ">" not in p + assert "|" not in p def test_sanitize_windows_replaces_trailing_space(self): with _common.platform_windows(): p = util.sanitize_path("one/two /three") - self.assertNotIn(" ", p) + assert " " not in p def test_sanitize_path_works_on_empty_string(self): with _common.platform_posix(): p = util.sanitize_path("") - self.assertEqual(p, "") + assert p == "" def test_sanitize_with_custom_replace_overrides_built_in_sub(self): with _common.platform_posix(): - p = util.sanitize_path( - "a/.?/b", - [ - (re.compile(r"foo"), "bar"), - ], - ) - self.assertEqual(p, "a/.?/b") + p = util.sanitize_path("a/.?/b", [(re.compile(r"foo"), "bar")]) + assert p == "a/.?/b" def test_sanitize_with_custom_replace_adds_replacements(self): with _common.platform_posix(): - p = util.sanitize_path( - "foo/bar", - [ - (re.compile(r"foo"), "bar"), - ], - ) - self.assertEqual(p, "bar/bar") + p = util.sanitize_path("foo/bar", [(re.compile(r"foo"), "bar")]) + assert p == "bar/bar" @unittest.skip("unimplemented: #359") def test_sanitize_empty_component(self): with _common.platform_posix(): - p = util.sanitize_path( - "foo//bar", - [ - (re.compile(r"^$"), "_"), - ], - ) - self.assertEqual(p, "foo/_/bar") + p = util.sanitize_path("foo//bar", [(re.compile(r"^$"), "_")]) + assert p == "foo/_/bar" @unittest.skipIf(sys.platform == "win32", "win32") def test_convert_command_args_keeps_undecodeable_bytes(self): arg = b"\x82" # non-ascii bytes cmd_args = util.convert_command_args([arg]) - self.assertEqual( - cmd_args[0], arg.decode(util.arg_encoding(), "surrogateescape") - ) + assert cmd_args[0] == arg.decode(util.arg_encoding(), "surrogateescape") @patch("beets.util.subprocess.Popen") def test_command_output(self, mock_popen): @@ -128,10 +113,10 @@ def popen_fail(*args, **kwargs): return m mock_popen.side_effect = popen_fail - with self.assertRaises(subprocess.CalledProcessError) as exc_context: + with pytest.raises(subprocess.CalledProcessError) as exc_info: util.command_output(["taga", "\xc3\xa9"]) - self.assertEqual(exc_context.exception.returncode, 1) - self.assertEqual(exc_context.exception.cmd, "taga \xc3\xa9") + assert exc_info.value.returncode == 1 + assert exc_info.value.cmd == "taga \xc3\xa9" def test_case_sensitive_default(self): path = util.bytestring_path( @@ -140,10 +125,7 @@ def test_case_sensitive_default(self): ) ) - self.assertEqual( - util.case_sensitive(path), - platform.system() != "Windows", - ) + assert util.case_sensitive(path) == (platform.system() != "Windows") @unittest.skipIf(sys.platform == "win32", "fs is not case sensitive") def test_case_sensitive_detects_sensitive(self): @@ -163,8 +145,8 @@ def test_syspath_windows_format(self): with _common.platform_windows(): path = os.path.join("a", "b", "c") outpath = util.syspath(path) - self.assertTrue(isinstance(outpath, str)) - self.assertTrue(outpath.startswith("\\\\?\\")) + assert isinstance(outpath, str) + assert outpath.startswith("\\\\?\\") def test_syspath_windows_format_unc_path(self): # The \\?\ prefix on Windows behaves differently with UNC @@ -172,14 +154,14 @@ def test_syspath_windows_format_unc_path(self): path = "\\\\server\\share\\file.mp3" with _common.platform_windows(): outpath = util.syspath(path) - self.assertTrue(isinstance(outpath, str)) - self.assertEqual(outpath, "\\\\?\\UNC\\server\\share\\file.mp3") + assert isinstance(outpath, str) + assert outpath == "\\\\?\\UNC\\server\\share\\file.mp3" def test_syspath_posix_unchanged(self): with _common.platform_posix(): path = os.path.join("a", "b", "c") outpath = util.syspath(path) - self.assertEqual(path, outpath) + assert path == outpath def _windows_bytestring_path(self, path): old_gfse = sys.getfilesystemencoding @@ -193,26 +175,26 @@ def _windows_bytestring_path(self, path): def test_bytestring_path_windows_encodes_utf8(self): path = "caf\xe9" outpath = self._windows_bytestring_path(path) - self.assertEqual(path, outpath.decode("utf-8")) + assert path == outpath.decode("utf-8") def test_bytesting_path_windows_removes_magic_prefix(self): path = "\\\\?\\C:\\caf\xe9" outpath = self._windows_bytestring_path(path) - self.assertEqual(outpath, "C:\\caf\xe9".encode()) + assert outpath == "C:\\caf\xe9".encode() class PathTruncationTest(BeetsTestCase): def test_truncate_bytestring(self): with _common.platform_posix(): p = util.truncate_path(b"abcde/fgh", 4) - self.assertEqual(p, b"abcd/fgh") + assert p == b"abcd/fgh" def test_truncate_unicode(self): with _common.platform_posix(): p = util.truncate_path("abcde/fgh", 4) - self.assertEqual(p, "abcd/fgh") + assert p == "abcd/fgh" def test_truncate_preserves_extension(self): with _common.platform_posix(): p = util.truncate_path("abcde/fgh.ext", 5) - self.assertEqual(p, "abcde/f.ext") + assert p == "abcde/f.ext" diff --git a/test/test_vfs.py b/test/test_vfs.py index 1586493f97..41ad276f5d 100644 --- a/test/test_vfs.py +++ b/test/test_vfs.py @@ -32,11 +32,11 @@ def setUp(self): self.tree = vfs.libtree(self.lib) def test_singleton_item(self): - self.assertEqual( - self.tree.dirs["tracks"].dirs["the artist"].files["the title"], 1 + assert ( + self.tree.dirs["tracks"].dirs["the artist"].files["the title"] == 1 ) def test_album_item(self): - self.assertEqual( - self.tree.dirs["albums"].dirs["the album"].files["the title"], 2 + assert ( + self.tree.dirs["albums"].dirs["the album"].files["the title"] == 2 )