Replace unittest assert methods by assert statement (#5386)

... continuing the test suite migration to `pytest` (#5361), this PR
replaces `unittest` method assertions with `assert` statement.

See the table below for a list of the replaced methods and their counts.
This should help clarify the size of the pull request 😆.

To keep things simple for the review, I have replaced each method in its
own commit. This
way, things should be easy to follow if you step through the commits one
by one. 🙂

method                   | count
---                      | ---
**`assertEqual`**        | 1747
**`assertIn`**           | 200
**`assertTrue`**         | 149
**`assertIsNone`**       | 87
**`assertFalse`**        | 85
**`assertRaises`**       | 69
**`assertNotIn`**        | 64
**`assertNotEqual`**     | 39
**`assertIsNotNone`**    | 35
**`assertIsInstance`**   | 35
**`assertLessEqual`**    | 23
**`assertGreater`**      | 15
**`assertLess`**         | 14
**`assertGreaterEqual`** | 14
**`assertAlmostEqual`**  | 9
**`assertRaisesRegex`**  | 4
**`assertCountEqual`**   | 2
**`assertListEqual`**    | 1


 Note that this *only* replaces methods provided by
`unittest` by default.
**Custom** assertion method replacements (like `assertExists` will be
addressed in a separate PR).
This commit is contained in:
Šarūnas Nejus 2024-08-19 08:08:16 +01:00 committed by GitHub
commit 38a26af149
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
70 changed files with 2961 additions and 3269 deletions

View file

@ -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.

View file

@ -644,7 +644,7 @@ class ImportHelper(TestHelper):
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:

View file

@ -30,9 +30,10 @@ class MapDataToSchemeTest(unittest.TestCase):
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 @@ class MapDataToSchemeTest(unittest.TestCase):
},
}
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 @@ class MapDataToSchemeTest(unittest.TestCase):
("moods_mirex", "Cluster3"),
("timbre", "bright"),
}
self.assertEqual(mapping, expected)
assert mapping == expected

View file

@ -16,6 +16,8 @@
"""
import pytest
from beets.test.helper import PluginTestCase
from beets.ui import UserError
@ -35,7 +37,7 @@ class AdvancedRewritePluginTest(PluginTestCase):
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 @@ class AdvancedRewritePluginTest(PluginTestCase):
)
# 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 @@ class AdvancedRewritePluginTest(PluginTestCase):
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 @@ class AdvancedRewritePluginTest(PluginTestCase):
]
):
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"

View file

@ -35,7 +35,7 @@ class AlbumTypesPluginTest(PluginTestCase):
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 @@ class AlbumTypesPluginTest(PluginTestCase):
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 @@ class AlbumTypesPluginTest(PluginTestCase):
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 @@ class AlbumTypesPluginTest(PluginTestCase):
)
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 @@ class AlbumTypesPluginTest(PluginTestCase):
)
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,

View file

@ -20,6 +20,7 @@ import shutil
from unittest.mock import patch
import confuse
import pytest
import responses
from beets import config, importer, logging, util
@ -209,23 +210,23 @@ class FetchImageTest(FetchImageTestCase):
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 @@ class FSArtTest(UseThePlugin):
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 @@ class FSArtTest(UseThePlugin):
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 @@ class CombinedTest(FetchImageTestCase, CAAHelper):
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 @@ class CombinedTest(FetchImageTestCase, CAAHelper):
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 @@ class CombinedTest(FetchImageTestCase, CAAHelper):
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 @@ class AAOTest(UseThePlugin):
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 @@ class ITunesStoreTest(UseThePlugin):
}"""
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 @@ class ITunesStoreTest(UseThePlugin):
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 @@ class ITunesStoreTest(UseThePlugin):
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 @@ class ITunesStoreTest(UseThePlugin):
}"""
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 @@ class ITunesStoreTest(UseThePlugin):
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 @@ class ITunesStoreTest(UseThePlugin):
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 @@ class ITunesStoreTest(UseThePlugin):
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 @@ class GoogleImageTest(UseThePlugin):
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 @@ class CoverArtArchiveTest(UseThePlugin, CAAHelper):
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 @@ class CoverArtArchiveTest(UseThePlugin, CAAHelper):
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 @@ class CoverArtArchiveTest(UseThePlugin, CAAHelper):
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 @@ class FanartTVTest(UseThePlugin):
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 @@ class FanartTVTest(UseThePlugin):
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 @@ class FanartTVTest(UseThePlugin):
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 @@ class FanartTVTest(UseThePlugin):
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 @@ class ArtImporterTest(UseThePlugin):
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 @@ class ArtForAlbumTest(UseThePlugin):
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 @@ class ArtForAlbumTest(UseThePlugin):
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 @@ class DeprecatedConfigTest(BeetsTestCase):
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 @@ class EnforceRatioConfigTest(BeetsTestCase):
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:

View file

@ -62,16 +62,14 @@ class BareascPluginTest(PluginTestCase):
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 @@ class BareascPluginTest(PluginTestCase):
"bareasc", "with accents", "-f", "$artist:: $title"
)
self.assertEqual("Antonin Dvorak:: with accents\n", output.getvalue())
assert "Antonin Dvorak:: with accents\n" == output.getvalue()

View file

@ -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 @@ class BeatportTest(BeetsTestCase):
# 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 @@ class BeatportTest(BeetsTestCase):
]
# 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 @@ class BeatportResponseEmptyTest(BeetsTestCase):
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 @@ class BeatportResponseEmptyTest(BeetsTestCase):
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 @@ class BeatportResponseEmptyTest(BeetsTestCase):
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"]

View file

@ -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 @@ class BucketPluginTest(BeetsTestCase):
"""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 @@ class BucketPluginTest(BeetsTestCase):
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 @@ class BucketPluginTest(BeetsTestCase):
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)

View file

@ -64,13 +64,9 @@ class ConvertMixin:
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 @@ class ConvertMixin:
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 @@ class ImportConvertTest(AsIsImporterMixin, ImportHelper, ConvertTestCase):
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 @@ class ImportConvertTest(AsIsImporterMixin, ImportHelper, ConvertTestCase):
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 @@ class ConvertCliTest(ConvertTestCase, ConvertCommand):
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 @@ class ConvertCliTest(ConvertTestCase, ConvertCommand):
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 @@ class ConvertCliTest(ConvertTestCase, ConvertCommand):
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 @@ class ConvertCliTest(ConvertTestCase, ConvertCommand):
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()

View file

@ -94,59 +94,59 @@ class DGAlbumInfoTest(BeetsTestCase):
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 @@ class DGAlbumInfoTest(BeetsTestCase):
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 @@ class DGAlbumInfoTest(BeetsTestCase):
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 @@ class DGAlbumInfoTest(BeetsTestCase):
)
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 @@ class DGAlbumInfoTest(BeetsTestCase):
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 @@ class DGAlbumInfoTest(BeetsTestCase):
]
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 @@ class DGAlbumInfoTest(BeetsTestCase):
]
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 @@ class DGAlbumInfoTest(BeetsTestCase):
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 @@ class DGAlbumInfoTest(BeetsTestCase):
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 @@ class DGAlbumInfoTest(BeetsTestCase):
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 @@ class DGAlbumInfoTest(BeetsTestCase):
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 @@ class DGAlbumInfoTest(BeetsTestCase):
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 @@ class DGAlbumInfoTest(BeetsTestCase):
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

View file

@ -94,7 +94,7 @@ class EditMixin(PluginMixin):
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 @@ class EditCommandTest(EditMixin, BeetsTestCase):
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 @@ class EditCommandTest(EditMixin, BeetsTestCase):
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 @@ class EditCommandTest(EditMixin, BeetsTestCase):
)
# 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 @@ class EditCommandTest(EditMixin, BeetsTestCase):
["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 @@ class EditCommandTest(EditMixin, BeetsTestCase):
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 @@ class EditCommandTest(EditMixin, BeetsTestCase):
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 @@ class EditDuringImporterNonSingletonTest(EditDuringImporterTestCase):
"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 @@ class EditDuringImporterNonSingletonTest(EditDuringImporterTestCase):
[],
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 @@ class EditDuringImporterNonSingletonTest(EditDuringImporterTestCase):
# 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 @@ class EditDuringImporterNonSingletonTest(EditDuringImporterTestCase):
# 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 @@ class EditDuringImporterNonSingletonTest(EditDuringImporterTestCase):
# 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 @@ class EditDuringImporterNonSingletonTest(EditDuringImporterTestCase):
# 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 @@ class EditDuringImporterSingletonTest(EditDuringImporterTestCase):
["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())

View file

@ -20,6 +20,7 @@ import unittest
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 @@ class EmbedartCliTest(PluginMixin, FetchImageHelper, BeetsTestCase):
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 @@ class EmbedartCliTest(PluginMixin, FetchImageHelper, BeetsTestCase):
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 @@ class EmbedartCliTest(PluginMixin, FetchImageHelper, BeetsTestCase):
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 @@ class EmbedartCliTest(PluginMixin, FetchImageHelper, BeetsTestCase):
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 @@ class EmbedartCliTest(PluginMixin, FetchImageHelper, BeetsTestCase):
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 @@ class EmbedartCliTest(PluginMixin, FetchImageHelper, BeetsTestCase):
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 @@ class EmbedartCliTest(PluginMixin, FetchImageHelper, BeetsTestCase):
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 @@ class EmbedartCliTest(PluginMixin, FetchImageHelper, BeetsTestCase):
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 @@ class EmbedartCliTest(PluginMixin, FetchImageHelper, BeetsTestCase):
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 @@ class EmbedartCliTest(PluginMixin, FetchImageHelper, BeetsTestCase):
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 @@ class EmbedartCliTest(PluginMixin, FetchImageHelper, BeetsTestCase):
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 @@ class EmbedartCliTest(PluginMixin, FetchImageHelper, BeetsTestCase):
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 @@ class EmbedartCliTest(PluginMixin, FetchImageHelper, BeetsTestCase):
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 @@ class ArtSimilarityTest(unittest.TestCase):
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

View file

@ -18,80 +18,73 @@ class EmbyUpdateTest(PluginTestCase):
}
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 @@ class EmbyUpdateTest(PluginTestCase):
"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 @@ class EmbyUpdateTest(PluginTestCase):
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"

View file

@ -52,16 +52,16 @@ class ExportPluginTest(PluginTestCase):
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 @@ class ExportPluginTest(PluginTestCase):
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

View file

@ -32,9 +32,9 @@ class FetchartCliTest(PluginTestCase):
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 @@ class FetchartCliTest(PluginTestCase):
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 @@ class FetchartCliTest(PluginTestCase):
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")

View file

@ -45,8 +45,8 @@ class FileFilterPluginMixin(PluginMixin, ImportTestCase):
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):

View file

@ -42,38 +42,38 @@ class FtInTitlePluginFunctional(PluginTestCase):
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 @@ class FtInTitlePluginTest(unittest.TestCase):
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")

View file

@ -44,26 +44,24 @@ class HookLogsTest(HookTestCase):
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 @@ class HookCommandTest(HookTestCase):
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):

View file

@ -16,30 +16,30 @@ class IHatePluginTest(unittest.TestCase):
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)

View file

@ -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 @@ class ImportAddedTest(PluginMixin, ImportTestCase):
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 @@ class ImportAddedTest(PluginMixin, ImportTestCase):
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)

View file

@ -27,9 +27,9 @@ class ImportfeedsTestTest(BeetsTestCase):
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 @@ class ImportfeedsTestTest(BeetsTestCase):
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 @@ class ImportfeedsTestTest(BeetsTestCase):
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()

View file

@ -33,11 +33,11 @@ class InfoTest(PluginTestCase):
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 @@ class InfoTest(PluginTestCase):
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 @@ class InfoTest(PluginTestCase):
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 @@ class InfoTest(PluginTestCase):
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 @@ class InfoTest(PluginTestCase):
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 @@ class InfoTest(PluginTestCase):
"--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

View file

@ -30,7 +30,7 @@ class IPFSPluginTest(PluginTestCase):
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 @@ class IPFSPluginTest(PluginTestCase):
)
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)]

View file

@ -32,7 +32,7 @@ class KeyFinderTest(AsIsImporterMixin, PluginMixin, ImportTestCase):
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 @@ class KeyFinderTest(AsIsImporterMixin, PluginMixin, ImportTestCase):
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 @@ class KeyFinderTest(AsIsImporterMixin, PluginMixin, ImportTestCase):
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 @@ class KeyFinderTest(AsIsImporterMixin, PluginMixin, ImportTestCase):
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 @@ class KeyFinderTest(AsIsImporterMixin, PluginMixin, ImportTestCase):
self.run_command("keyfinder")
item.load()
self.assertIsNone(item["initial_key"])
assert item["initial_key"] is None

View file

@ -14,7 +14,6 @@
"""Tests for the 'lastgenre' plugin."""
from unittest.mock import Mock
from beets import config
@ -45,50 +44,46 @@ class LastGenrePluginTest(BeetsTestCase):
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 @@ class LastGenrePluginTest(BeetsTestCase):
)
# 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 @@ class LastGenrePluginTest(BeetsTestCase):
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 @@ class LastGenrePluginTest(BeetsTestCase):
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"]

View file

@ -49,47 +49,47 @@ class LimitPluginTest(PluginTestCase):
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

View file

@ -45,116 +45,106 @@ class LyricsPluginTest(unittest.TestCase):
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 @@ class LyricsPluginTest(unittest.TestCase):
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 = """<!--lyrics below-->
@ -176,26 +166,22 @@ class LyricsPluginTest(unittest.TestCase):
two !
<br><br \\>
<blink>four</blink>"""
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 = """foo<script>bar</script>baz"""
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 = """foo<!--<bar>-->qux"""
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</p> <p class='myclass'>two</p><p>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 @@ class LyricsPluginSourcesTest(LyricsGoogleBaseTest, LyricsAssertions):
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 @@ class LyricsGooglePluginMachineryTest(LyricsGoogleBaseTest, LyricsAssertions):
"""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 @@ class LyricsGooglePluginMachineryTest(LyricsGoogleBaseTest, LyricsAssertions):
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 @@ class LyricsGooglePluginMachineryTest(LyricsGoogleBaseTest, LyricsAssertions):
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 @@ class GeniusScrapeLyricsFromHtmlTest(GeniusBaseTest):
# 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 @@ class GeniusFetchTest(GeniusBaseTest):
) 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 @@ class TekstowoExtractLyricsTest(TekstowoBaseTest):
"""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 @@ class TekstowoExtractLyricsTest(TekstowoBaseTest):
"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 @@ class TekstowoExtractLyricsTest(TekstowoBaseTest):
",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 @@ class TekstowoParseSearchResultsTest(TekstowoBaseTest):
",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 @@ class TekstowoParseSearchResultsTest(TekstowoBaseTest):
"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 @@ class TekstowoIntegrationTest(TekstowoBaseTest, LyricsAssertions):
# 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 @@ class LRCLibLyricsTest(unittest.TestCase):
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 @@ class LRCLibLyricsTest(unittest.TestCase):
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 @@ class LRCLibLyricsTest(unittest.TestCase):
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 @@ class LRCLibLyricsTest(unittest.TestCase):
lyrics = lrclib.fetch("la", "la", "la", 999)
self.assertIsNone(lyrics)
assert lyrics is None
class LRCLibIntegrationTest(LyricsAssertions):
@ -769,12 +751,9 @@ class LRCLibIntegrationTest(LyricsAssertions):
)
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 @@ class LRCLibIntegrationTest(LyricsAssertions):
)
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)

View file

@ -51,7 +51,7 @@ class MBSubmitPluginTest(PluginMixin, TerminalImportMixin, ImportTestCase):
"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 @@ class MBSubmitPluginTest(PluginMixin, TerminalImportMixin, ImportTestCase):
tracklist = (
"Open files with Picard? " "02. Tag Track 2 - Tag Artist (0:01)"
)
self.assertIn(tracklist, output.getvalue())
assert tracklist in output.getvalue()

View file

@ -57,18 +57,18 @@ class MbsyncCliTest(PluginTestCase):
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 @@ class MbsyncCliTest(PluginTestCase):
"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 @@ class MbsyncCliTest(PluginTestCase):
"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 @@ class MbsyncCliTest(PluginTestCase):
"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 @@ class MbsyncCliTest(PluginTestCase):
"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]

View file

@ -31,8 +31,8 @@ class MPDStatsTest(PluginTestCase):
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 @@ class MPDStatsTest(PluginTestCase):
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 = [

View file

@ -105,9 +105,7 @@ class ParentWorkIntegrationTest(PluginTestCase):
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 @@ class ParentWorkIntegrationTest(PluginTestCase):
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 @@ class ParentWorkIntegrationTest(PluginTestCase):
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 @@ class ParentWorkIntegrationTest(PluginTestCase):
)
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 @@ class ParentWorkTest(PluginTestCase):
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 @@ class ParentWorkTest(PluginTestCase):
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 @@ class ParentWorkTest(PluginTestCase):
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]

View file

@ -74,13 +74,13 @@ class PermissionsPluginTest(AsIsImporterMixin, PluginMixin, ImportTestCase):
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 @@ class PermissionsPluginTest(AsIsImporterMixin, PluginMixin, ImportTestCase):
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)

View file

@ -20,6 +20,8 @@ import sys
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 @@ class PlayPluginTest(CleanupModulesMixin, PluginTestCase):
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 @@ class PlayPluginTest(CleanupModulesMixin, PluginTestCase):
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 @@ class PlayPluginTest(CleanupModulesMixin, PluginTestCase):
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")

View file

@ -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 contextlib import contextmanager
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 implements(commands, expectedFailure=False): # noqa: N803
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 @@ class BPDTestHelper(PluginTestCase):
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 @@ class BPDTestHelper(PluginTestCase):
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 @@ class BPDTestHelper(PluginTestCase):
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 @@ class BPDQueryTest(BPDTestHelper):
("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 @@ class BPDQueryTest(BPDTestHelper):
"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 @@ class BPDQueryTest(BPDTestHelper):
"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 @@ class BPDQueryTest(BPDTestHelper):
"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 @@ class BPDQueryTest(BPDTestHelper):
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 @@ class BPDPlaybackTest(BPDTestHelper):
("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 @@ class BPDPlaybackTest(BPDTestHelper):
("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 @@ class BPDPlaybackTest(BPDTestHelper):
("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 @@ class BPDPlaybackTest(BPDTestHelper):
("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 @@ class BPDPlaybackTest(BPDTestHelper):
("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 @@ class BPDPlaybackTest(BPDTestHelper):
("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 @@ class BPDPlaybackTest(BPDTestHelper):
("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 @@ class BPDPlaybackTest(BPDTestHelper):
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 @@ class BPDPlaybackTest(BPDTestHelper):
("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 @@ class BPDPlaybackTest(BPDTestHelper):
("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 @@ class BPDPlaybackTest(BPDTestHelper):
("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 @@ class BPDPlaybackTest(BPDTestHelper):
("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 @@ class BPDControlTest(BPDTestHelper):
("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 @@ class BPDControlTest(BPDTestHelper):
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 @@ class BPDControlTest(BPDTestHelper):
("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 @@ class BPDControlTest(BPDTestHelper):
("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 @@ class BPDControlTest(BPDTestHelper):
("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 @@ class BPDControlTest(BPDTestHelper):
("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 @@ class BPDQueueTest(BPDTestHelper):
("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 @@ class BPDQueueTest(BPDTestHelper):
("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 @@ class BPDDatabaseTest(BPDTestHelper):
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 @@ class BPDDatabaseTest(BPDTestHelper):
("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 @@ class BPDDatabaseTest(BPDTestHelper):
("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 @@ class BPDDatabaseTest(BPDTestHelper):
"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 @@ class BPDConnectionTest(BPDTestHelper):
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 @@ class BPDReflectionTest(BPDTestHelper):
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):

View file

@ -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 @@ class PlaylistQueryTest:
)
)
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 @@ class PlaylistQueryTest:
)
)
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 @@ class PlaylistQueryTest:
)
)
results = self.lib.items(q)
self.assertEqual(set(results), set())
assert set(results) == set()
class PlaylistTestRelativeToLib(PlaylistQueryTest, PlaylistTestCase):
@ -313,28 +289,22 @@ class PlaylistTestItemMoved(PlaylistUpdateTest, PlaylistTestCase):
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 @@ class PlaylistTestItemRemoved(PlaylistUpdateTest, PlaylistTestCase):
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"]

View file

@ -83,7 +83,7 @@ class PlexUpdateTest(PluginTestCase):
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 @@ class PlexUpdateTest(PluginTestCase):
self.config["plex"]["library_name"].get(),
self.config["plex"]["secure"],
self.config["plex"]["ignore_cert_errors"],
),
"2",
)
== "2"
)
@responses.activate
@ -100,7 +100,7 @@ class PlexUpdateTest(PluginTestCase):
# 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 @@ class PlexUpdateTest(PluginTestCase):
"My Music Library",
self.config["plex"]["secure"],
self.config["plex"]["ignore_cert_errors"],
),
"2",
)
== "2"
)
@responses.activate
@ -119,7 +119,7 @@ class PlexUpdateTest(PluginTestCase):
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 @@ class PlexUpdateTest(PluginTestCase):
self.config["plex"]["library_name"].get(),
self.config["plex"]["secure"],
self.config["plex"]["ignore_cert_errors"],
).status_code,
200,
).status_code
== 200
)

View file

@ -19,6 +19,7 @@ import os
import shutil
import mediafile
import pytest
from beets.library import Item
from beets.plugins import BeetsPlugin
@ -59,7 +60,7 @@ class ExtendedFieldTestMixin(BeetsTestCase):
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 @@ class ExtendedFieldTestMixin(BeetsTestCase):
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 @@ class ExtendedFieldTestMixin(BeetsTestCase):
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 @@ class ExtendedFieldTestMixin(BeetsTestCase):
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))

View file

@ -20,6 +20,8 @@ import math
import unittest
from random import Random
import pytest
from beets import random
from beets.test.helper import TestHelper
@ -74,6 +76,6 @@ class RandomTest(TestHelper, unittest.TestCase):
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

View file

@ -16,6 +16,7 @@
import unittest
from typing import ClassVar
import pytest
from mediafile import MediaFile
from beets import config
@ -129,11 +130,11 @@ class ReplayGainCliTest:
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 @@ class ReplayGainCliTest:
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 @@ class ReplayGainCliTest:
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 @@ class ReplayGainCliTest:
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 @@ class ReplayGainCliTest:
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 @@ class ReplayGainCliTest:
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 @@ class ReplayGainCliTest:
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 @@ class ReplayGainCliTest:
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 @@ class ReplayGainCliTest:
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 @@ class ReplayGainCliTest:
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 @@ class ReplayGainCliTest:
# 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 @@ class ImportTest(AsIsImporterMixin):
# 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")

View file

@ -18,6 +18,8 @@ from shutil import rmtree
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 @@ from beetsplug.smartplaylist import SmartPlaylistPlugin
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 @@ class SmartPlaylistTest(BeetsTestCase):
]
)
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 @@ class SmartPlaylistTest(BeetsTestCase):
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 @@ class SmartPlaylistTest(BeetsTestCase):
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 @@ class SmartPlaylistTest(BeetsTestCase):
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 @@ class SmartPlaylistTest(BeetsTestCase):
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 @@ class SmartPlaylistTest(BeetsTestCase):
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 @@ class SmartPlaylistTest(BeetsTestCase):
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 @@ class SmartPlaylistTest(BeetsTestCase):
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 @@ class SmartPlaylistTest(BeetsTestCase):
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 @@ class SmartPlaylistCLITest(PluginTestCase):
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"

View file

@ -45,12 +45,12 @@ class SpotifyPluginTest(BeetsTestCase):
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 @@ class SpotifyPluginTest(BeetsTestCase):
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 @@ class SpotifyPluginTest(BeetsTestCase):
)
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 @@ class SpotifyPluginTest(BeetsTestCase):
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"]

View file

@ -7,55 +7,43 @@ from beetsplug.the import FORMAT, PATTERN_A, PATTERN_THE, ThePlugin
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"
assert ThePlugin().unthe("", PATTERN_THE) == ""
assert (
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"
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"
)
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("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)"

View file

@ -18,6 +18,8 @@ from shutil import rmtree
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 @@ class ThumbnailsTest(BeetsTestCase):
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 @@ class ThumbnailsTest(BeetsTestCase):
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 @@ class ThumbnailsTest(BeetsTestCase):
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 @@ class ThumbnailsTest(BeetsTestCase):
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 @@ class ThumbnailsTest(BeetsTestCase):
# 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 @@ class ThumbnailsTest(BeetsTestCase):
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 @@ class ThumbnailsTest(BeetsTestCase):
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"
)

View file

@ -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 @@ class TypesPluginTest(PluginTestCase):
# 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 @@ class TypesPluginTest(PluginTestCase):
# 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 @@ class TypesPluginTest(PluginTestCase):
# 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 @@ class TypesPluginTest(PluginTestCase):
# 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 @@ class TypesPluginTest(PluginTestCase):
# 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 @@ class TypesPluginTest(PluginTestCase):
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(

View file

@ -4,6 +4,7 @@ import json
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 @@ class WebPluginTest(ItemInDBTestCase):
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 @@ class WebPluginTest(ItemInDBTestCase):
+ 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 @@ class WebPluginTest(ItemInDBTestCase):
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 @@ class WebPluginTest(ItemInDBTestCase):
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 @@ class WebPluginTest(ItemInDBTestCase):
# 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: <empty>"""
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 @@ class WebPluginTest(ItemInDBTestCase):
)
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 @@ class WebPluginTest(ItemInDBTestCase):
# 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 @@ class WebPluginTest(ItemInDBTestCase):
# 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 @@ class WebPluginTest(ItemInDBTestCase):
# 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 @@ class WebPluginTest(ItemInDBTestCase):
# 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 @@ class WebPluginTest(ItemInDBTestCase):
# 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 @@ class WebPluginTest(ItemInDBTestCase):
# 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 @@ class WebPluginTest(ItemInDBTestCase):
# 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 @@ class WebPluginTest(ItemInDBTestCase):
# 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 @@ class WebPluginTest(ItemInDBTestCase):
# 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 @@ class WebPluginTest(ItemInDBTestCase):
# 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 @@ class WebPluginTest(ItemInDBTestCase):
# 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 @@ class WebPluginTest(ItemInDBTestCase):
# 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 @@ class WebPluginTest(ItemInDBTestCase):
# 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 @@ class WebPluginTest(ItemInDBTestCase):
"/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 @@ class WebPluginTest(ItemInDBTestCase):
# 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 @@ class WebPluginTest(ItemInDBTestCase):
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

View file

@ -25,10 +25,10 @@ class ZeroPluginTest(PluginTestCase):
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 @@ class ZeroPluginTest(PluginTestCase):
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 @@ class ZeroPluginTest(PluginTestCase):
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 @@ class ZeroPluginTest(PluginTestCase):
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 @@ class ZeroPluginTest(PluginTestCase):
):
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 @@ class ZeroPluginTest(PluginTestCase):
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 @@ class ZeroPluginTest(PluginTestCase):
):
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 @@ class ZeroPluginTest(PluginTestCase):
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 @@ class ZeroPluginTest(PluginTestCase):
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 @@ class ZeroPluginTest(PluginTestCase):
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 @@ class ZeroPluginTest(PluginTestCase):
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 @@ class ZeroPluginTest(PluginTestCase):
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 @@ class ZeroPluginTest(PluginTestCase):
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 @@ class ZeroPluginTest(PluginTestCase):
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 @@ class ZeroPluginTest(PluginTestCase):
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 @@ class ZeroPluginTest(PluginTestCase):
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 @@ class ZeroPluginTest(PluginTestCase):
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"

View file

@ -77,8 +77,9 @@ class ArtResizerFileSizeTest(CleanupModulesMixin, BeetsTestCase):
)
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 @@ class ArtResizerFileSizeTest(CleanupModulesMixin, BeetsTestCase):
)
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 @@ class ArtResizerFileSizeTest(CleanupModulesMixin, BeetsTestCase):
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 @@ class ArtResizerFileSizeTest(CleanupModulesMixin, BeetsTestCase):
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):

View file

@ -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 @@ class PluralityTest(BeetsTestCase):
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 @@ class PluralityTest(BeetsTestCase):
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 @@ class PluralityTest(BeetsTestCase):
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 @@ class PluralityTest(BeetsTestCase):
"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 @@ class DistanceTest(BeetsTestCase):
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 @@ class DistanceTest(BeetsTestCase):
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 @@ class DistanceTest(BeetsTestCase):
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 @@ class DistanceTest(BeetsTestCase):
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 @@ class DistanceTest(BeetsTestCase):
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 @@ class DistanceTest(BeetsTestCase):
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 @@ class DistanceTest(BeetsTestCase):
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 @@ class TrackDistanceTest(BeetsTestCase):
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 @@ class AlbumDistanceTest(BeetsTestCase):
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 @@ class AlbumDistanceTest(BeetsTestCase):
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 @@ class AlbumDistanceTest(BeetsTestCase):
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 @@ class AlbumDistanceTest(BeetsTestCase):
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 @@ class AlbumDistanceTest(BeetsTestCase):
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 @@ class AlbumDistanceTest(BeetsTestCase):
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 @@ class AlbumDistanceTest(BeetsTestCase):
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 @@ class AlbumDistanceTest(BeetsTestCase):
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 @@ class AlbumDistanceTest(BeetsTestCase):
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 @@ class AssignmentTest(unittest.TestCase):
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 @@ class AssignmentTest(unittest.TestCase):
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 @@ class AssignmentTest(unittest.TestCase):
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 @@ class AssignmentTest(unittest.TestCase):
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 @@ class AssignmentTest(unittest.TestCase):
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 @@ class ApplyTest(BeetsTestCase, ApplyTestUtil):
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 @@ class ApplyTest(BeetsTestCase, ApplyTestUtil):
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 @@ class ApplyTest(BeetsTestCase, ApplyTestUtil):
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 @@ class ApplyTest(BeetsTestCase, ApplyTestUtil):
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 @@ class ApplyTest(BeetsTestCase, ApplyTestUtil):
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 @@ class ApplyCompilationTest(BeetsTestCase, ApplyTestUtil):
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 @@ class StringDistanceTest(unittest.TestCase):
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 @@ class EnumTest(BeetsTestCase):
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

View file

@ -1,6 +1,7 @@
import os
from unittest.mock import patch
import pytest
import yaml
from beets import config, ui
@ -37,52 +38,52 @@ class ConfigCommandTest(BeetsTestCase):
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 @@ class ConfigCommandTest(BeetsTestCase):
)
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:

View file

@ -19,6 +19,8 @@ import time
import unittest
from datetime import datetime, timedelta
import pytest
from beets.dbcore.query import (
DateInterval,
DateQuery,
@ -139,13 +141,13 @@ class DateIntervalTest(unittest.TestCase):
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 @@ class DateQueryTest(ItemInDBTestCase):
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 @@ class DateQueryTestRelative(ItemInDBTestCase):
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 @@ class DateQueryTestRelativeMore(ItemInDBTestCase):
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 @@ class DateQueryConstructTest(unittest.TestCase):
"..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")

View file

@ -20,6 +20,8 @@ import sqlite3
import unittest
from tempfile import mkstemp
import pytest
from beets import dbcore
from beets.test import _common
@ -190,7 +192,7 @@ class MigrationTest(unittest.TestCase):
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 @@ class MigrationTest(unittest.TestCase):
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 @@ class MigrationTest(unittest.TestCase):
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 @@ class MigrationTest(unittest.TestCase):
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 @@ class TransactionTest(unittest.TestCase):
"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 @@ class ModelTest(unittest.TestCase):
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 @@ class ModelTest(unittest.TestCase):
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 @@ class ModelTest(unittest.TestCase):
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 @@ class ModelTest(unittest.TestCase):
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 @@ class ModelTest(unittest.TestCase):
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 @@ class ModelTest(unittest.TestCase):
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 @@ class FormatTest(unittest.TestCase):
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 @@ class QueryParseTest(unittest.TestCase):
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 @@ class QueryFromStringsTest(unittest.TestCase):
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 @@ class SortFromStringsTest(unittest.TestCase):
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 @@ class ParseSortedQueryTest(unittest.TestCase):
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 @@ class ResultsIteratorTest(unittest.TestCase):
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 @@ class ResultsIteratorTest(unittest.TestCase):
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
)

View file

@ -21,6 +21,8 @@ import stat
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 @@ class MoveTest(BeetsTestCase):
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 @@ class MoveTest(BeetsTestCase):
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 @@ class MoveTest(BeetsTestCase):
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 @@ class MoveTest(BeetsTestCase):
@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 @@ class MoveTest(BeetsTestCase):
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 @@ class MoveTest(BeetsTestCase):
@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 @@ class AlbumFileTest(BeetsTestCase):
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 @@ class AlbumFileTest(BeetsTestCase):
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 @@ class ArtFileTest(BeetsTestCase):
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 @@ class ArtFileTest(BeetsTestCase):
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 @@ class ArtFileTest(BeetsTestCase):
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 @@ class ArtFileTest(BeetsTestCase):
# 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 @@ class ArtFileTest(BeetsTestCase):
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 @@ class ArtFileTest(BeetsTestCase):
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 @@ class ArtFileTest(BeetsTestCase):
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 @@ class SafeMoveCopyTest(BeetsTestCase):
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 @@ class WalkTest(BeetsTestCase):
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 @@ class UniquePathTest(BeetsTestCase):
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):

View file

@ -45,7 +45,7 @@ class HiddenFileTest(unittest.TestCase):
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 @@ class HiddenFileTest(unittest.TestCase):
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 @@ class HiddenFileTest(unittest.TestCase):
with tempfile.NamedTemporaryFile(prefix=".tmp") as f:
fn = util.bytestring_path(f.name)
self.assertTrue(hidden.is_hidden(fn))
assert hidden.is_hidden(fn)

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -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 @@ class LoggingTest(BeetsTestCase):
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 @@ class LoggingLevelTest(AsIsImporterMixin, PluginMixin, ImportTestCase):
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 @@ class ConcurrentEventsTest(AsIsImporterMixin, ImportTestCase):
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 @@ class ConcurrentEventsTest(AsIsImporterMixin, ImportTestCase):
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 @@ class ConcurrentEventsTest(AsIsImporterMixin, ImportTestCase):
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

View file

@ -20,6 +20,8 @@ from os import path
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 @@ class M3UFileTest(unittest.TestCase):
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 @@ class M3UFileTest(unittest.TestCase):
]
)
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 @@ class M3UFileTest(unittest.TestCase):
]
)
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 @@ class M3UFileTest(unittest.TestCase):
]
)
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 @@ class M3UFileTest(unittest.TestCase):
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 @@ class M3UFileTest(unittest.TestCase):
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 @@ class M3UFileTest(unittest.TestCase):
)
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

View file

@ -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 @@ class MBAlbumInfoTest(BeetsTestCase):
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 @@ class MBAlbumInfoTest(BeetsTestCase):
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 @@ class MBAlbumInfoTest(BeetsTestCase):
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 @@ class MBAlbumInfoTest(BeetsTestCase):
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 @@ class MBAlbumInfoTest(BeetsTestCase):
)
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 @@ class MBAlbumInfoTest(BeetsTestCase):
]
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 @@ class MBAlbumInfoTest(BeetsTestCase):
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 @@ class MBAlbumInfoTest(BeetsTestCase):
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"
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_id, "TRACK ARTIST ID")
self.assertEqual(
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 @@ class MBAlbumInfoTest(BeetsTestCase):
]
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 @@ class MBAlbumInfoTest(BeetsTestCase):
]
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 @@ class MBAlbumInfoTest(BeetsTestCase):
]
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 @@ class MBAlbumInfoTest(BeetsTestCase):
]
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 @@ class MBAlbumInfoTest(BeetsTestCase):
]
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 @@ class MBAlbumInfoTest(BeetsTestCase):
]
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 @@ class MBAlbumInfoTest(BeetsTestCase):
]
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 @@ class MBAlbumInfoTest(BeetsTestCase):
]
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 @@ class MBAlbumInfoTest(BeetsTestCase):
]
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 @@ class MBAlbumInfoTest(BeetsTestCase):
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 @@ class ArtistFlatteningTest(BeetsTestCase):
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 @@ class ArtistFlatteningTest(BeetsTestCase):
# 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 @@ class MBLibraryTest(unittest.TestCase):
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 @@ class MBLibraryTest(unittest.TestCase):
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 @@ class MBLibraryTest(unittest.TestCase):
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 @@ class MBLibraryTest(unittest.TestCase):
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 @@ class MBLibraryTest(unittest.TestCase):
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 @@ class MBLibraryTest(unittest.TestCase):
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

View file

@ -84,46 +84,42 @@ class MetaSyncTest(PluginTestCase):
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")

View file

@ -17,6 +17,8 @@
import unittest
import pytest
from beets.util import pipeline
@ -78,20 +80,20 @@ class SimplePipelineTest(unittest.TestCase):
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 @@ class ParallelStageTest(unittest.TestCase):
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 @@ class ExceptionTest(unittest.TestCase):
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 @@ class ParallelExceptionTest(unittest.TestCase):
)
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 @@ class ConstrainedThreadedPipelineTest(unittest.TestCase):
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 @@ class ConstrainedThreadedPipelineTest(unittest.TestCase):
(_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 @@ class BubbleTest(unittest.TestCase):
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 @@ class MultiMessageTest(unittest.TestCase):
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 @@ class StageDecoratorTest(unittest.TestCase):
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 @@ class StageDecoratorTest(unittest.TestCase):
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}]

View file

@ -18,6 +18,7 @@ import os
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 ItemTypesTest(PluginLoaderTestCase):
# 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 @@ class ItemWriteTest(PluginLoaderTestCase):
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 ItemTypeConflictTest(PluginLoaderTestCase):
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 ItemTypeConflictTest(PluginLoaderTestCase):
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 @@ class EventsTest(PluginImportTestCase):
# 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 @@ class EventsTest(PluginImportTestCase):
# 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 @@ class ListenersTest(PluginLoaderTestCase):
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 @@ class ListenersTest(PluginLoaderTestCase):
@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 @@ class ListenersTest(PluginLoaderTestCase):
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 @@ class ListenersTest(PluginLoaderTestCase):
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 @@ class ListenersTest(PluginLoaderTestCase):
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 @@ class PromptChoicesTest(TerminalImportMixin, PluginImportTestCase):
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 @@ class ParseBeatportIDTest(unittest.TestCase):
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

View file

@ -21,6 +21,8 @@ import unittest
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 @@ WIN32_NO_IMPLICIT_PATHS = "Implicit paths are not supported on Windows"
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 @@ class AnyFieldQueryTest(ItemInDBTestCase):
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 @@ class AnyFieldQueryTest(ItemInDBTestCase):
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 @@ class GetTest(DummyDataTestCase):
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 @@ class GetTest(DummyDataTestCase):
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 @@ class GetTest(DummyDataTestCase):
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 @@ class MatchTest(BeetsTestCase):
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 @@ class MatchTest(BeetsTestCase):
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 @@ class PathQueryTest(ItemInDBTestCase, AssertsMixin):
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 @@ class PathQueryTest(ItemInDBTestCase, AssertsMixin):
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 @@ class PathQueryTest(ItemInDBTestCase, AssertsMixin):
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 @@ class IntQueryTest(BeetsTestCase):
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 @@ class BoolQueryTest(BeetsTestCase, AssertsMixin):
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 @@ class NoneQueryTest(BeetsTestCase, AssertsMixin):
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 @@ class NotQueryMatchTest(BeetsTestCase):
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 @@ class NotQueryTest(DummyDataTestCase):
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 @@ class NotQueryTest(DummyDataTestCase):
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

View file

@ -107,25 +107,25 @@ class SortFixedFieldTest(DummyDataTestCase):
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 @@ class SortFixedFieldTest(DummyDataTestCase):
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 @@ class SortFlexFieldTest(DummyDataTestCase):
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 @@ class SortFlexFieldTest(DummyDataTestCase):
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 @@ class SortAlbumFixedFieldTest(DummyDataTestCase):
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 @@ class SortAlbumFixedFieldTest(DummyDataTestCase):
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 @@ class SortAlbumFlexFieldTest(DummyDataTestCase):
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 @@ class SortAlbumFlexFieldTest(DummyDataTestCase):
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 @@ class SortAlbumComputedFieldTest(DummyDataTestCase):
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 @@ class SortCombinedFieldTest(DummyDataTestCase):
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 @@ class SortCombinedFieldTest(DummyDataTestCase):
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 @@ class CaseSensitivityTest(DummyDataTestCase, BeetsTestCase):
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 @@ class CaseSensitivityTest(DummyDataTestCase, BeetsTestCase):
# 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 @@ class NonExistingFieldTest(DummyDataTestCase):
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 @@ class NonExistingFieldTest(DummyDataTestCase):
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 @@ class NonExistingFieldTest(DummyDataTestCase):
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"

View file

@ -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 @@ class EvalTest(unittest.TestCase):
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"

File diff suppressed because it is too large Load diff

View file

@ -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 @@ class QueryTest(BeetsTestCase):
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 @@ class FieldsTest(ItemInDBTestCase):
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

View file

@ -44,14 +44,14 @@ class InputMethodsTest(BeetsTestCase):
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 @@ class InputMethodsTest(BeetsTestCase):
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 @@ class InputMethodsTest(BeetsTestCase):
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 @@ class InputMethodsTest(BeetsTestCase):
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 @@ class InitTest(ItemInDBTestCase):
(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 @@ class InitTest(ItemInDBTestCase):
(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):

View file

@ -22,6 +22,8 @@ import sys
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 @@ from beets.test.helper import BeetsTestCase
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 @@ class UtilTest(unittest.TestCase):
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 @@ class UtilTest(unittest.TestCase):
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 @@ class UtilTest(unittest.TestCase):
)
)
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 @@ class PathConversionTest(BeetsTestCase):
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 @@ class PathConversionTest(BeetsTestCase):
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 @@ class PathConversionTest(BeetsTestCase):
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"

View file

@ -32,11 +32,11 @@ class VFSTest(BeetsTestCase):
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
)