mirror of
https://github.com/beetbox/beets.git
synced 2026-01-04 15:03:22 +01:00
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:
commit
38a26af149
70 changed files with 2961 additions and 3269 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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"]
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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 = [
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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"]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"]
|
||||
|
|
|
|||
|
|
@ -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)"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
350
test/test_mb.py
350
test/test_mb.py
|
|
@ -12,10 +12,8 @@
|
|||
# The above copyright notice and this permission notice shall be
|
||||
# included in all copies or substantial portions of the Software.
|
||||
|
||||
"""Tests for MusicBrainz API wrapper.
|
||||
"""
|
||||
"""Tests for MusicBrainz API wrapper."""
|
||||
|
||||
import unittest
|
||||
from unittest import mock
|
||||
|
||||
from beets import config
|
||||
|
|
@ -213,25 +211,25 @@ 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
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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}]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
467
test/test_ui.py
467
test/test_ui.py
File diff suppressed because it is too large
Load diff
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in a new issue