From 7689a1e95aa3e8005601ebd921c264776f992fa8 Mon Sep 17 00:00:00 2001 From: Hugo Date: Mon, 1 Jun 2020 14:52:29 +0300 Subject: [PATCH 1/6] User.get_now_playing: Add album and cover image to info --- src/pylast/__init__.py | 3 ++- tests/test_network.py | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/pylast/__init__.py b/src/pylast/__init__.py index 5ddab60d..4befdb7a 100644 --- a/src/pylast/__init__.py +++ b/src/pylast/__init__.py @@ -2338,8 +2338,9 @@ def get_now_playing(self): artist = _extract(e, "artist") title = _extract(e, "name") + info = {"album": _extract(e, "album"), "image": _extract_all(e, "image")} - return Track(artist, title, self.network, self.name) + return Track(artist, title, self.network, self.name, info=info) def get_recent_tracks(self, limit=10, cacheable=True, time_from=None, time_to=None): """ diff --git a/tests/test_network.py b/tests/test_network.py index 36188ec6..95587e98 100755 --- a/tests/test_network.py +++ b/tests/test_network.py @@ -47,6 +47,10 @@ def test_update_now_playing(self): self.assertIsNotNone(current_track) self.assertEqual(str(current_track.title).lower(), "test title") self.assertEqual(str(current_track.artist).lower(), "test artist") + self.assertEqual(current_track.info["album"], "Test Album") + + self.assertTrue(len(current_track.info["image"])) + self.assertRegex(current_track.info["image"][pylast.SIZE_LARGE], r"^http.+$") def test_enable_rate_limiting(self): # Arrange From 8437316d3d89dd7631a5892eeb19d7ca2b600808 Mon Sep 17 00:00:00 2001 From: Hugo Date: Mon, 1 Jun 2020 14:57:33 +0300 Subject: [PATCH 2/6] pre-commit autoupdate --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1802b34f..8461ec42 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/asottile/pyupgrade - rev: v2.4.1 + rev: v2.4.4 hooks: - id: pyupgrade args: ["--py3-plus"] @@ -15,7 +15,7 @@ repos: types: [] - repo: https://gitlab.com/pycqa/flake8 - rev: 3.8.0a2 + rev: 3.8.2 hooks: - id: flake8 additional_dependencies: [flake8-2020, flake8-implicit-str-concat] @@ -36,7 +36,7 @@ repos: - id: python-check-blanket-noqa - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v2.5.0 + rev: v3.1.0 hooks: - id: check-merge-conflict - id: check-yaml From 1160ee151327bc71d028e10de9c5bf761a7b6237 Mon Sep 17 00:00:00 2001 From: Hugo Date: Mon, 1 Jun 2020 15:20:36 +0300 Subject: [PATCH 3/6] GHA: Simplify and update lint.yml --- .github/workflows/lint.yml | 39 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 03896a5b..13f3f435 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -4,39 +4,34 @@ on: [push, pull_request] jobs: build: - runs-on: ubuntu-latest - strategy: - matrix: - python-version: [3.8] + runs-on: ubuntu-18.04 steps: - uses: actions/checkout@v2 - - name: pip cache - uses: actions/cache@v1 + - name: Cache + uses: actions/cache@v2 with: - path: ~/.cache/pip - key: lint-pip-${{ hashFiles('**/setup.py') }} + path: | + ~/.cache/pip + ~/.cache/pre-commit + key: + lint-v2-${{ hashFiles('**/setup.py') }}-${{ + hashFiles('**/.pre-commit-config.yaml') }} restore-keys: | - lint-pip- + lint-v2- - - name: pre-commit cache - uses: actions/cache@v1 + - name: Set up Python + uses: actions/setup-python@v2 with: - path: ~/.cache/pre-commit - key: lint-pre-commit-v1-${{ hashFiles('**/.pre-commit-config.yaml') }} - restore-keys: | - lint-pre-commit-v1- - - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v1 - with: - python-version: ${{ matrix.python-version }} + python-version: 3.8 - name: Install dependencies run: | - python -m pip install --upgrade pip - python -m pip install --upgrade tox + python -m pip install -U pip + python -m pip install -U tox - name: Lint run: tox -e lint + env: + PRE_COMMIT_COLOR: always From aae4bb3693e3331a526eb4eb93f0f5c01e26dc94 Mon Sep 17 00:00:00 2001 From: Hugo Date: Mon, 1 Jun 2020 15:50:27 +0300 Subject: [PATCH 4/6] Replace unittest with pytest --- tests/test_album.py | 28 ++++----- tests/test_artist.py | 78 +++++++++++------------- tests/test_country.py | 18 ++---- tests/test_library.py | 8 +-- tests/test_librefm.py | 8 +-- tests/test_network.py | 139 ++++++++++++++++++++---------------------- tests/test_pylast.py | 84 ++++++++++++------------- tests/test_tag.py | 20 +++--- tests/test_track.py | 74 +++++++++++----------- tests/test_user.py | 101 +++++++++++++++--------------- 10 files changed, 253 insertions(+), 305 deletions(-) diff --git a/tests/test_album.py b/tests/test_album.py index 878e4e13..8a213b54 100755 --- a/tests/test_album.py +++ b/tests/test_album.py @@ -2,8 +2,6 @@ """ Integration (not unit) tests for pylast.py """ -import unittest - import pylast from .test_pylast import TestPyLastWithLastFm @@ -18,8 +16,8 @@ def test_album_tags_are_topitems(self): tags = album.get_top_tags(limit=1) # Assert - self.assertGreater(len(tags), 0) - self.assertIsInstance(tags[0], pylast.TopItem) + assert len(tags) > 0 + assert isinstance(tags[0], pylast.TopItem) def test_album_is_hashable(self): # Arrange @@ -37,7 +35,7 @@ def test_album_in_recent_tracks(self): track = lastfm_user.get_recent_tracks(limit=2)[0] # Assert - self.assertTrue(hasattr(track, "album")) + assert hasattr(track, "album") def test_album_wiki_content(self): # Arrange @@ -47,8 +45,8 @@ def test_album_wiki_content(self): wiki = album.get_wiki_content() # Assert - self.assertIsNotNone(wiki) - self.assertGreaterEqual(len(wiki), 1) + assert wiki is not None + assert len(wiki) >= 1 def test_album_wiki_published_date(self): # Arrange @@ -58,8 +56,8 @@ def test_album_wiki_published_date(self): wiki = album.get_wiki_published_date() # Assert - self.assertIsNotNone(wiki) - self.assertGreaterEqual(len(wiki), 1) + assert wiki is not None + assert len(wiki) >= 1 def test_album_wiki_summary(self): # Arrange @@ -69,8 +67,8 @@ def test_album_wiki_summary(self): wiki = album.get_wiki_summary() # Assert - self.assertIsNotNone(wiki) - self.assertGreaterEqual(len(wiki), 1) + assert wiki is not None + assert len(wiki) >= 1 def test_album_eq_none_is_false(self): # Arrange @@ -78,7 +76,7 @@ def test_album_eq_none_is_false(self): album2 = pylast.Album("Test Artist", "Test Album", self.network) # Act / Assert - self.assertNotEqual(album1, album2) + assert album1 != album2 def test_album_ne_none_is_true(self): # Arrange @@ -86,7 +84,7 @@ def test_album_ne_none_is_true(self): album2 = pylast.Album("Test Artist", "Test Album", self.network) # Act / Assert - self.assertNotEqual(album1, album2) + assert album1 != album2 def test_get_cover_image(self): # Arrange @@ -98,7 +96,3 @@ def test_get_cover_image(self): # Assert self.assert_startswith(image, "https://") self.assert_endswith(image, ".png") - - -if __name__ == "__main__": - unittest.main(failfast=True) diff --git a/tests/test_artist.py b/tests/test_artist.py index 8837261e..aa3e0075 100755 --- a/tests/test_artist.py +++ b/tests/test_artist.py @@ -2,8 +2,6 @@ """ Integration (not unit) tests for pylast.py """ -import unittest - import pylast import pytest @@ -19,13 +17,13 @@ def test_repr(self): representation = repr(artist) # Assert - self.assertTrue(representation.startswith("pylast.Artist('Test Artist',")) + assert representation.startswith("pylast.Artist('Test Artist',") def test_artist_is_hashable(self): # Arrange test_artist = self.network.get_artist("Test Artist") artist = test_artist.get_similar(limit=2)[0].item - self.assertIsInstance(artist, pylast.Artist) + assert isinstance(artist, pylast.Artist) # Act/Assert self.helper_is_thing_hashable(artist) @@ -38,8 +36,8 @@ def test_bio_published_date(self): bio = artist.get_bio_published_date() # Assert - self.assertIsNotNone(bio) - self.assertGreaterEqual(len(bio), 1) + assert bio is not None + assert len(bio) >= 1 def test_bio_content(self): # Arrange @@ -49,8 +47,8 @@ def test_bio_content(self): bio = artist.get_bio_content(language="en") # Assert - self.assertIsNotNone(bio) - self.assertGreaterEqual(len(bio), 1) + assert bio is not None + assert len(bio) >= 1 def test_bio_content_none(self): # Arrange @@ -61,7 +59,7 @@ def test_bio_content_none(self): bio = artist.get_bio_content() # Assert - self.assertIsNone(bio) + assert bio is None def test_bio_summary(self): # Arrange @@ -71,8 +69,8 @@ def test_bio_summary(self): bio = artist.get_bio_summary(language="en") # Assert - self.assertIsNotNone(bio) - self.assertGreaterEqual(len(bio), 1) + assert bio is not None + assert len(bio) >= 1 def test_artist_top_tracks(self): # Arrange @@ -106,7 +104,7 @@ def test_artist_top_albums_limit_1(self): things = artist.get_top_albums(limit=limit) # Assert - self.assertEqual(len(things), 1) + assert len(things) == 1 def test_artist_top_albums_limit_50(self): # Arrange @@ -118,7 +116,7 @@ def test_artist_top_albums_limit_50(self): things = artist.get_top_albums(limit=limit) # Assert - self.assertEqual(len(things), 50) + assert len(things) == 50 def test_artist_top_albums_limit_100(self): # Arrange @@ -130,7 +128,7 @@ def test_artist_top_albums_limit_100(self): things = artist.get_top_albums(limit=limit) # Assert - self.assertEqual(len(things), 100) + assert len(things) == 100 def test_artist_listener_count(self): # Arrange @@ -140,8 +138,8 @@ def test_artist_listener_count(self): count = artist.get_listener_count() # Assert - self.assertIsInstance(count, int) - self.assertGreater(count, 0) + assert isinstance(count, int) + assert count > 0 def test_tag_artist(self): # Arrange @@ -153,13 +151,13 @@ def test_tag_artist(self): # Assert tags = artist.get_tags() - self.assertGreater(len(tags), 0) + assert len(tags) > 0 found = False for tag in tags: if tag.name == "testing": found = True break - self.assertTrue(found) + assert found def test_remove_tag_of_type_text(self): # Arrange @@ -177,7 +175,7 @@ def test_remove_tag_of_type_text(self): if tag.name == "testing": found = True break - self.assertFalse(found) + assert not found def test_remove_tag_of_type_tag(self): # Arrange @@ -195,7 +193,7 @@ def test_remove_tag_of_type_tag(self): if tag.name == "testing": found = True break - self.assertFalse(found) + assert not found def test_remove_tags(self): # Arrange @@ -210,15 +208,15 @@ def test_remove_tags(self): # Assert tags_after = artist.get_tags() - self.assertEqual(len(tags_after), len(tags_before) - 2) + assert len(tags_after) == len(tags_before) - 2 found1, found2 = False, False for tag in tags_after: if tag.name == "removetag1": found1 = True elif tag.name == "removetag2": found2 = True - self.assertFalse(found1) - self.assertFalse(found2) + assert not found1 + assert not found2 def test_set_tags(self): # Arrange @@ -233,16 +231,16 @@ def test_set_tags(self): # Assert tags_after = artist.get_tags() - self.assertNotEqual(tags_before, tags_after) - self.assertEqual(len(tags_after), 2) + assert tags_before != tags_after + assert len(tags_after) == 2 found1, found2 = False, False for tag in tags_after: if tag.name == "settag1": found1 = True elif tag.name == "settag2": found2 = True - self.assertTrue(found1) - self.assertTrue(found2) + assert found1 + assert found2 def test_artists(self): # Arrange @@ -259,13 +257,13 @@ def test_artists(self): name_cap = artist1.get_name(properly_capitalized=True) # Assert - self.assertIn("https", image) - self.assertGreater(playcount, 1) - self.assertNotEqual(artist1, artist2) - self.assertEqual(name.lower(), name_cap.lower()) - self.assertEqual(url, "https://www.last.fm/music/radiohead") - self.assertEqual(mbid, "a74b1b7f-71a5-4011-9441-d0b5e4122711") - self.assertIsInstance(streamable, bool) + assert "https" in image + assert playcount > 1 + assert artist1 != artist2 + assert name.lower() == name_cap.lower() + assert url == "https://www.last.fm/music/radiohead" + assert mbid == "a74b1b7f-71a5-4011-9441-d0b5e4122711" + assert isinstance(streamable, bool) def test_artist_eq_none_is_false(self): # Arrange @@ -273,7 +271,7 @@ def test_artist_eq_none_is_false(self): artist2 = pylast.Artist("Test Artist", self.network) # Act / Assert - self.assertNotEqual(artist1, artist2) + assert artist1 != artist2 def test_artist_ne_none_is_true(self): # Arrange @@ -281,7 +279,7 @@ def test_artist_ne_none_is_true(self): artist2 = pylast.Artist("Test Artist", self.network) # Act / Assert - self.assertNotEqual(artist1, artist2) + assert artist1 != artist2 def test_artist_get_correction(self): # Arrange @@ -291,7 +289,7 @@ def test_artist_get_correction(self): corrected_artist_name = artist.get_correction() # Assert - self.assertEqual(corrected_artist_name, "Guns N' Roses") + assert corrected_artist_name == "Guns N' Roses" @pytest.mark.xfail def test_get_userplaycount(self): @@ -302,8 +300,4 @@ def test_get_userplaycount(self): playcount = artist.get_userplaycount() # Assert - self.assertGreaterEqual(playcount, 0) - - -if __name__ == "__main__": - unittest.main(failfast=True) + assert playcount >= 0 diff --git a/tests/test_country.py b/tests/test_country.py index 1eede36d..4561d82b 100755 --- a/tests/test_country.py +++ b/tests/test_country.py @@ -2,8 +2,6 @@ """ Integration (not unit) tests for pylast.py """ -import unittest - import pylast from .test_pylast import TestPyLastWithLastFm @@ -28,13 +26,9 @@ def test_countries(self): url = country1.get_url() # Assert - self.assertIn("Italy", rep) - self.assertIn("pylast.Country", rep) - self.assertEqual(text, "Italy") - self.assertEqual(country1, country1) - self.assertNotEqual(country1, country2) - self.assertEqual(url, "https://www.last.fm/place/italy") - - -if __name__ == "__main__": - unittest.main(failfast=True) + assert "Italy" in rep + assert "pylast.Country" in rep + assert text == "Italy" + assert country1 == country1 + assert country1 != country2 + assert url == "https://www.last.fm/place/italy" diff --git a/tests/test_library.py b/tests/test_library.py index 3b3de36b..dea876d9 100755 --- a/tests/test_library.py +++ b/tests/test_library.py @@ -2,8 +2,6 @@ """ Integration (not unit) tests for pylast.py """ -import unittest - import pylast from .test_pylast import TestPyLastWithLastFm @@ -53,8 +51,4 @@ def test_get_user(self): library_user = library.get_user() # Assert - self.assertEqual(library_user, user_to_get) - - -if __name__ == "__main__": - unittest.main(failfast=True) + assert library_user == user_to_get diff --git a/tests/test_librefm.py b/tests/test_librefm.py index 7f8d54b2..cb8ddccc 100755 --- a/tests/test_librefm.py +++ b/tests/test_librefm.py @@ -2,8 +2,6 @@ """ Integration (not unit) tests for pylast.py """ -import unittest - import pylast from flaky import flaky @@ -26,7 +24,7 @@ def test_libre_fm(self): name = artist.get_name() # Assert - self.assertEqual(name, "Radiohead") + assert name == "Radiohead" def test_repr(self): # Arrange @@ -40,7 +38,3 @@ def test_repr(self): # Assert self.assert_startswith(representation, "pylast.LibreFMNetwork(") - - -if __name__ == "__main__": - unittest.main(failfast=True) diff --git a/tests/test_network.py b/tests/test_network.py index 95587e98..85362a34 100755 --- a/tests/test_network.py +++ b/tests/test_network.py @@ -2,16 +2,17 @@ """ Integration (not unit) tests for pylast.py """ +import re import time -import unittest import pylast +import pytest from .test_pylast import PY37, TestPyLastWithLastFm class TestPyLastNetwork(TestPyLastWithLastFm): - @unittest.skipUnless(PY37, "Only run on Python 3.7 to avoid collisions") + @pytest.mark.skipif(not PY37, reason="Only run on Python 3.7 to avoid collisions") def test_scrobble(self): # Arrange artist = "test artist" @@ -26,8 +27,8 @@ def test_scrobble(self): # Assert # limit=2 to ignore now-playing: last_scrobble = lastfm_user.get_recent_tracks(limit=2)[0] - self.assertEqual(str(last_scrobble.track.artist).lower(), artist) - self.assertEqual(str(last_scrobble.track.title).lower(), title) + assert str(last_scrobble.track.artist).lower() == artist + assert str(last_scrobble.track.title).lower() == title def test_update_now_playing(self): # Arrange @@ -44,17 +45,17 @@ def test_update_now_playing(self): # Assert current_track = lastfm_user.get_now_playing() - self.assertIsNotNone(current_track) - self.assertEqual(str(current_track.title).lower(), "test title") - self.assertEqual(str(current_track.artist).lower(), "test artist") - self.assertEqual(current_track.info["album"], "Test Album") + assert current_track is not None + assert str(current_track.title).lower() == "test title" + assert str(current_track.artist).lower() == "test artist" + assert current_track.info["album"] == "Test Album" - self.assertTrue(len(current_track.info["image"])) - self.assertRegex(current_track.info["image"][pylast.SIZE_LARGE], r"^http.+$") + assert len(current_track.info["image"]) + assert re.search(r"^http.+$", current_track.info["image"][pylast.SIZE_LARGE]) def test_enable_rate_limiting(self): # Arrange - self.assertFalse(self.network.is_rate_limited()) + assert not self.network.is_rate_limited() # Act self.network.enable_rate_limit() @@ -66,13 +67,13 @@ def test_enable_rate_limiting(self): now = time.time() # Assert - self.assertTrue(self.network.is_rate_limited()) - self.assertGreaterEqual(now - then, 0.2) + assert self.network.is_rate_limited() + assert now - then >= 0.2 def test_disable_rate_limiting(self): # Arrange self.network.enable_rate_limit() - self.assertTrue(self.network.is_rate_limited()) + assert self.network.is_rate_limited() # Act self.network.disable_rate_limit() @@ -82,14 +83,14 @@ def test_disable_rate_limiting(self): self.network.get_top_artists() # Assert - self.assertFalse(self.network.is_rate_limited()) + assert not self.network.is_rate_limited() def test_lastfm_network_name(self): # Act name = str(self.network) # Assert - self.assertEqual(name, "Last.fm Network") + assert name == "Last.fm Network" def test_geo_get_top_artists(self): # Arrange @@ -97,9 +98,9 @@ def test_geo_get_top_artists(self): artists = self.network.get_geo_top_artists(country="United Kingdom", limit=1) # Assert - self.assertEqual(len(artists), 1) - self.assertIsInstance(artists[0], pylast.TopItem) - self.assertIsInstance(artists[0].item, pylast.Artist) + assert len(artists) == 1 + assert isinstance(artists[0], pylast.TopItem) + assert isinstance(artists[0].item, pylast.Artist) def test_geo_get_top_tracks(self): # Arrange @@ -109,9 +110,9 @@ def test_geo_get_top_tracks(self): ) # Assert - self.assertEqual(len(tracks), 1) - self.assertIsInstance(tracks[0], pylast.TopItem) - self.assertIsInstance(tracks[0].item, pylast.Track) + assert len(tracks) == 1 + assert isinstance(tracks[0], pylast.TopItem) + assert isinstance(tracks[0].item, pylast.Track) def test_network_get_top_artists_with_limit(self): # Arrange @@ -186,12 +187,12 @@ def test_album_data(self): url = thing.get_url() # Assert - self.assertEqual(stringed, "Test Artist - Test Album") - self.assertIn("pylast.Album('Test Artist', 'Test Album',", rep) - self.assertEqual(title, name) - self.assertIsInstance(playcount, int) - self.assertGreater(playcount, 1) - self.assertEqual("https://www.last.fm/music/test%2bartist/test%2balbum", url) + assert stringed == "Test Artist - Test Album" + assert "pylast.Album('Test Artist', 'Test Album'," in rep + assert title == name + assert isinstance(playcount, int) + assert playcount > 1 + assert "https://www.last.fm/music/test%2bartist/test%2balbum" == url def test_track_data(self): # Arrange @@ -206,15 +207,13 @@ def test_track_data(self): url = thing.get_url(pylast.DOMAIN_FRENCH) # Assert - self.assertEqual(stringed, "Test Artist - test title") - self.assertIn("pylast.Track('Test Artist', 'test title',", rep) - self.assertEqual(title, "test title") - self.assertEqual(title, name) - self.assertIsInstance(playcount, int) - self.assertGreater(playcount, 1) - self.assertEqual( - "https://www.last.fm/fr/music/test%2bartist/_/test%2btitle", url - ) + assert stringed == "Test Artist - test title" + assert "pylast.Track('Test Artist', 'test title'," in rep + assert title == "test title" + assert title == name + assert isinstance(playcount, int) + assert playcount > 1 + assert "https://www.last.fm/fr/music/test%2bartist/_/test%2btitle" == url def test_country_top_artists(self): # Arrange @@ -236,10 +235,10 @@ def test_caching(self): tags2 = user.get_top_tags(limit=1, cacheable=True) # Assert - self.assertTrue(self.network.is_caching_enabled()) - self.assertEqual(tags1, tags2) + assert self.network.is_caching_enabled() + assert tags1 == tags2 self.network.disable_caching() - self.assertFalse(self.network.is_caching_enabled()) + assert not self.network.is_caching_enabled() def test_album_mbid(self): # Arrange @@ -250,9 +249,9 @@ def test_album_mbid(self): album_mbid = album.get_mbid() # Assert - self.assertIsInstance(album, pylast.Album) - self.assertEqual(album.title.lower(), "test") - self.assertEqual(album_mbid, mbid) + assert isinstance(album, pylast.Album) + assert album.title.lower() == "test" + assert album_mbid == mbid def test_artist_mbid(self): # Arrange @@ -262,8 +261,8 @@ def test_artist_mbid(self): artist = self.network.get_artist_by_mbid(mbid) # Assert - self.assertIsInstance(artist, pylast.Artist) - self.assertEqual(artist.name, "MusicBrainz Test Artist") + assert isinstance(artist, pylast.Artist) + assert artist.name == "MusicBrainz Test Artist" def test_track_mbid(self): # Arrange @@ -274,9 +273,9 @@ def test_track_mbid(self): track_mbid = track.get_mbid() # Assert - self.assertIsInstance(track, pylast.Track) - self.assertEqual(track.title, "first") - self.assertEqual(track_mbid, mbid) + assert isinstance(track, pylast.Track) + assert track.title == "first" + assert track_mbid == mbid def test_init_with_token(self): # Arrange/Act @@ -291,7 +290,7 @@ def test_init_with_token(self): msg = str(exc) # Assert - self.assertEqual(msg, "Unauthorized Token - This token has not been issued") + assert msg == "Unauthorized Token - This token has not been issued" def test_proxy(self): # Arrange @@ -300,11 +299,11 @@ def test_proxy(self): # Act / Assert self.network.enable_proxy(host, port) - self.assertTrue(self.network.is_proxy_enabled()) - self.assertEqual(self.network._get_proxy(), ["https://example.com", 1234]) + assert self.network.is_proxy_enabled() + assert self.network._get_proxy() == ["https://example.com", 1234] self.network.disable_proxy() - self.assertFalse(self.network.is_proxy_enabled()) + assert not self.network.is_proxy_enabled() def test_album_search(self): # Arrange @@ -315,8 +314,8 @@ def test_album_search(self): results = search.get_next_page() # Assert - self.assertIsInstance(results, list) - self.assertIsInstance(results[0], pylast.Album) + assert isinstance(results, list) + assert isinstance(results[0], pylast.Album) def test_album_search_images(self): # Arrange @@ -328,15 +327,15 @@ def test_album_search_images(self): images = results[0].info["image"] # Assert - self.assertEqual(len(images), 4) + assert len(images) == 4 self.assert_startswith(images[pylast.SIZE_SMALL], "https://") self.assert_endswith(images[pylast.SIZE_SMALL], ".png") - self.assertIn("/34s/", images[pylast.SIZE_SMALL]) + assert "/34s/" in images[pylast.SIZE_SMALL] self.assert_startswith(images[pylast.SIZE_EXTRA_LARGE], "https://") self.assert_endswith(images[pylast.SIZE_EXTRA_LARGE], ".png") - self.assertIn("/300x300/", images[pylast.SIZE_EXTRA_LARGE]) + assert "/300x300/" in images[pylast.SIZE_EXTRA_LARGE] def test_artist_search(self): # Arrange @@ -347,8 +346,8 @@ def test_artist_search(self): results = search.get_next_page() # Assert - self.assertIsInstance(results, list) - self.assertIsInstance(results[0], pylast.Artist) + assert isinstance(results, list) + assert isinstance(results[0], pylast.Artist) def test_artist_search_images(self): # Arrange @@ -360,15 +359,15 @@ def test_artist_search_images(self): images = results[0].info["image"] # Assert - self.assertEqual(len(images), 5) + assert len(images) == 5 self.assert_startswith(images[pylast.SIZE_SMALL], "https://") self.assert_endswith(images[pylast.SIZE_SMALL], ".png") - self.assertIn("/34s/", images[pylast.SIZE_SMALL]) + assert "/34s/" in images[pylast.SIZE_SMALL] self.assert_startswith(images[pylast.SIZE_EXTRA_LARGE], "https://") self.assert_endswith(images[pylast.SIZE_EXTRA_LARGE], ".png") - self.assertIn("/300x300/", images[pylast.SIZE_EXTRA_LARGE]) + assert "/300x300/" in images[pylast.SIZE_EXTRA_LARGE] def test_track_search(self): # Arrange @@ -380,8 +379,8 @@ def test_track_search(self): results = search.get_next_page() # Assert - self.assertIsInstance(results, list) - self.assertIsInstance(results[0], pylast.Track) + assert isinstance(results, list) + assert isinstance(results[0], pylast.Track) def test_track_search_images(self): # Arrange @@ -394,15 +393,15 @@ def test_track_search_images(self): images = results[0].info["image"] # Assert - self.assertEqual(len(images), 4) + assert len(images) == 4 self.assert_startswith(images[pylast.SIZE_SMALL], "https://") self.assert_endswith(images[pylast.SIZE_SMALL], ".png") - self.assertIn("/34s/", images[pylast.SIZE_SMALL]) + assert "/34s/" in images[pylast.SIZE_SMALL] self.assert_startswith(images[pylast.SIZE_EXTRA_LARGE], "https://") self.assert_endswith(images[pylast.SIZE_EXTRA_LARGE], ".png") - self.assertIn("/300x300/", images[pylast.SIZE_EXTRA_LARGE]) + assert "/300x300/" in images[pylast.SIZE_EXTRA_LARGE] def test_search_get_total_result_count(self): # Arrange @@ -414,8 +413,4 @@ def test_search_get_total_result_count(self): total = search.get_total_result_count() # Assert - self.assertGreater(int(total), 10000) - - -if __name__ == "__main__": - unittest.main(failfast=True) + assert int(total) > 10000 diff --git a/tests/test_pylast.py b/tests/test_pylast.py index c5a10b4e..6b86ce92 100755 --- a/tests/test_pylast.py +++ b/tests/test_pylast.py @@ -5,7 +5,6 @@ import os import sys import time -import unittest import pylast import pytest @@ -33,12 +32,12 @@ def load_secrets(): return doc -class PyLastTestCase(unittest.TestCase): +class PyLastTestCase: def assert_startswith(self, str, prefix, start=None, end=None): - self.assertTrue(str.startswith(prefix, start, end)) + assert str.startswith(prefix, start, end) def assert_endswith(self, str, suffix, start=None, end=None): - self.assertTrue(str.endswith(suffix, start, end)) + assert str.endswith(suffix, start, end) @flaky(max_runs=3, min_passes=1) @@ -49,20 +48,21 @@ class TestPyLastWithLastFm(PyLastTestCase): def unix_timestamp(self): return int(time.time()) - def setUp(self): - if self.__class__.secrets is None: - self.__class__.secrets = load_secrets() + @classmethod + def setup_class(cls): + if cls.secrets is None: + cls.secrets = load_secrets() - self.username = self.__class__.secrets["username"] - password_hash = self.__class__.secrets["password_hash"] + cls.username = cls.secrets["username"] + password_hash = cls.secrets["password_hash"] - api_key = self.__class__.secrets["api_key"] - api_secret = self.__class__.secrets["api_secret"] + api_key = cls.secrets["api_key"] + api_secret = cls.secrets["api_secret"] - self.network = pylast.LastFMNetwork( + cls.network = pylast.LastFMNetwork( api_key=api_key, api_secret=api_secret, - username=self.username, + username=cls.username, password_hash=password_hash, ) @@ -74,19 +74,19 @@ def helper_is_thing_hashable(self, thing): things.add(thing) # Assert - self.assertIsNotNone(thing) - self.assertEqual(len(things), 1) + assert thing is not None + assert len(things) == 1 def helper_validate_results(self, a, b, c): # Assert - self.assertIsNotNone(a) - self.assertIsNotNone(b) - self.assertIsNotNone(c) - self.assertGreaterEqual(len(a), 0) - self.assertGreaterEqual(len(b), 0) - self.assertGreaterEqual(len(c), 0) - self.assertEqual(a, b) - self.assertEqual(b, c) + assert a is not None + assert b is not None + assert c is not None + assert len(a) >= 0 + assert len(b) >= 0 + assert len(c) >= 0 + assert a == b + assert b == c def helper_validate_cacheable(self, thing, function_name): # Arrange @@ -103,35 +103,31 @@ def helper_validate_cacheable(self, thing, function_name): def helper_at_least_one_thing_in_top_list(self, things, expected_type): # Assert - self.assertGreater(len(things), 1) - self.assertIsInstance(things, list) - self.assertIsInstance(things[0], pylast.TopItem) - self.assertIsInstance(things[0].item, expected_type) + assert len(things) > 1 + assert isinstance(things, list) + assert isinstance(things[0], pylast.TopItem) + assert isinstance(things[0].item, expected_type) def helper_only_one_thing_in_top_list(self, things, expected_type): # Assert - self.assertEqual(len(things), 1) - self.assertIsInstance(things, list) - self.assertIsInstance(things[0], pylast.TopItem) - self.assertIsInstance(things[0].item, expected_type) + assert len(things) == 1 + assert isinstance(things, list) + assert isinstance(things[0], pylast.TopItem) + assert isinstance(things[0].item, expected_type) def helper_only_one_thing_in_list(self, things, expected_type): # Assert - self.assertEqual(len(things), 1) - self.assertIsInstance(things, list) - self.assertIsInstance(things[0], expected_type) + assert len(things) == 1 + assert isinstance(things, list) + assert isinstance(things[0], expected_type) def helper_two_different_things_in_top_list(self, things, expected_type): # Assert - self.assertEqual(len(things), 2) + assert len(things) == 2 thing1 = things[0] thing2 = things[1] - self.assertIsInstance(thing1, pylast.TopItem) - self.assertIsInstance(thing2, pylast.TopItem) - self.assertIsInstance(thing1.item, expected_type) - self.assertIsInstance(thing2.item, expected_type) - self.assertNotEqual(thing1, thing2) - - -if __name__ == "__main__": - unittest.main(failfast=True) + assert isinstance(thing1, pylast.TopItem) + assert isinstance(thing2, pylast.TopItem) + assert isinstance(thing1.item, expected_type) + assert isinstance(thing2.item, expected_type) + assert thing1 != thing2 diff --git a/tests/test_tag.py b/tests/test_tag.py index f589b949..65544e03 100755 --- a/tests/test_tag.py +++ b/tests/test_tag.py @@ -2,8 +2,6 @@ """ Integration (not unit) tests for pylast.py """ -import unittest - import pylast from .test_pylast import TestPyLastWithLastFm @@ -49,14 +47,10 @@ def test_tags(self): url = tag1.get_url() # Assert - self.assertEqual("blues", tag_str) - self.assertIn("pylast.Tag", tag_repr) - self.assertIn("blues", tag_repr) - self.assertEqual("blues", name) - self.assertEqual(tag1, tag1) - self.assertNotEqual(tag1, tag2) - self.assertEqual(url, "https://www.last.fm/tag/blues") - - -if __name__ == "__main__": - unittest.main(failfast=True) + assert "blues" == tag_str + assert "pylast.Tag" in tag_repr + assert "blues" in tag_repr + assert "blues" == name + assert tag1 == tag1 + assert tag1 != tag2 + assert url == "https://www.last.fm/tag/blues" diff --git a/tests/test_track.py b/tests/test_track.py index 9c1b8987..d3f5e6aa 100755 --- a/tests/test_track.py +++ b/tests/test_track.py @@ -3,9 +3,9 @@ Integration (not unit) tests for pylast.py """ import time -import unittest import pylast +import pytest from .test_pylast import PY37, TestPyLastWithLastFm @@ -23,10 +23,10 @@ def test_love(self): # Assert loved = lastfm_user.get_loved_tracks(limit=1) - self.assertEqual(str(loved[0].track.artist).lower(), "test artist") - self.assertEqual(str(loved[0].track.title).lower(), "test title") + assert str(loved[0].track.artist).lower() == "test artist" + assert str(loved[0].track.title).lower() == "test title" - @unittest.skipUnless(PY37, "Only run on Python 3.7 to avoid collisions") + @pytest.mark.skipif(not PY37, reason="Only run on Python 3.7 to avoid collisions") def test_unlove(self): # Arrange artist = pylast.Artist("Test Artist", self.network) @@ -42,8 +42,8 @@ def test_unlove(self): # Assert loved = lastfm_user.get_loved_tracks(limit=1) if len(loved): # OK to be empty but if not: - self.assertNotEqual(str(loved[0].track.artist), "Test Artist") - self.assertNotEqual(str(loved[0].track.title), "test title") + assert str(loved[0].track.artist) != "Test Artist" + assert str(loved[0].track.title) != "test title" def test_user_play_count_in_track_info(self): # Arrange @@ -57,7 +57,7 @@ def test_user_play_count_in_track_info(self): count = track.get_userplaycount() # Assert - self.assertGreaterEqual(count, 0) + assert count >= 0 def test_user_loved_in_track_info(self): # Arrange @@ -71,15 +71,15 @@ def test_user_loved_in_track_info(self): loved = track.get_userloved() # Assert - self.assertIsNotNone(loved) - self.assertIsInstance(loved, bool) - self.assertNotIsInstance(loved, str) + assert loved is not None + assert isinstance(loved, bool) + assert not isinstance(loved, str) def test_track_is_hashable(self): # Arrange artist = self.network.get_artist("Test Artist") track = artist.get_top_tracks()[0].item - self.assertIsInstance(track, pylast.Track) + assert isinstance(track, pylast.Track) # Act/Assert self.helper_is_thing_hashable(track) @@ -92,8 +92,8 @@ def test_track_wiki_content(self): wiki = track.get_wiki_content() # Assert - self.assertIsNotNone(wiki) - self.assertGreaterEqual(len(wiki), 1) + assert wiki is not None + assert len(wiki) >= 1 def test_track_wiki_summary(self): # Arrange @@ -103,8 +103,8 @@ def test_track_wiki_summary(self): wiki = track.get_wiki_summary() # Assert - self.assertIsNotNone(wiki) - self.assertGreaterEqual(len(wiki), 1) + assert wiki is not None + assert len(wiki) >= 1 def test_track_get_duration(self): # Arrange @@ -114,7 +114,7 @@ def test_track_get_duration(self): duration = track.get_duration() # Assert - self.assertGreaterEqual(duration, 200000) + assert duration >= 200000 def test_track_is_streamable(self): # Arrange @@ -124,7 +124,7 @@ def test_track_is_streamable(self): streamable = track.is_streamable() # Assert - self.assertFalse(streamable) + assert not streamable def test_track_is_fulltrack_available(self): # Arrange @@ -134,7 +134,7 @@ def test_track_is_fulltrack_available(self): fulltrack_available = track.is_fulltrack_available() # Assert - self.assertFalse(fulltrack_available) + assert not fulltrack_available def test_track_get_album(self): # Arrange @@ -144,7 +144,7 @@ def test_track_get_album(self): album = track.get_album() # Assert - self.assertEqual(str(album), "Nirvana - Nevermind") + assert str(album) == "Nirvana - Nevermind" def test_track_get_similar(self): # Arrange @@ -159,17 +159,17 @@ def test_track_get_similar(self): if str(track.item) == "Madonna - Vogue": found = True break - self.assertTrue(found) + assert found def test_track_get_similar_limits(self): # Arrange track = pylast.Track("Cher", "Believe", self.network) # Act/Assert - self.assertEqual(len(track.get_similar(limit=20)), 20) - self.assertLessEqual(len(track.get_similar(limit=10)), 10) - self.assertGreaterEqual(len(track.get_similar(limit=None)), 23) - self.assertGreaterEqual(len(track.get_similar(limit=0)), 23) + assert len(track.get_similar(limit=20)) == 20 + assert len(track.get_similar(limit=10)) <= 10 + assert len(track.get_similar(limit=None)) >= 23 + assert len(track.get_similar(limit=0)) >= 23 def test_tracks_notequal(self): # Arrange @@ -178,7 +178,7 @@ def test_tracks_notequal(self): # Act # Assert - self.assertNotEqual(track1, track2) + assert track1 != track2 def test_track_title_prop_caps(self): # Arrange @@ -188,7 +188,7 @@ def test_track_title_prop_caps(self): title = track.get_title(properly_capitalized=True) # Assert - self.assertEqual(title, "Test Title") + assert title == "Test Title" def test_track_listener_count(self): # Arrange @@ -198,7 +198,7 @@ def test_track_listener_count(self): count = track.get_listener_count() # Assert - self.assertGreater(count, 21) + assert count > 21 def test_album_tracks(self): # Arrange @@ -209,10 +209,10 @@ def test_album_tracks(self): url = tracks[0].get_url() # Assert - self.assertIsInstance(tracks, list) - self.assertIsInstance(tracks[0], pylast.Track) - self.assertEqual(len(tracks), 1) - self.assertTrue(url.startswith("https://www.last.fm/music/test")) + assert isinstance(tracks, list) + assert isinstance(tracks[0], pylast.Track) + assert len(tracks) == 1 + assert url.startswith("https://www.last.fm/music/test") def test_track_eq_none_is_false(self): # Arrange @@ -220,7 +220,7 @@ def test_track_eq_none_is_false(self): track2 = pylast.Track("Test Artist", "test title", self.network) # Act / Assert - self.assertNotEqual(track1, track2) + assert track1 != track2 def test_track_ne_none_is_true(self): # Arrange @@ -228,7 +228,7 @@ def test_track_ne_none_is_true(self): track2 = pylast.Track("Test Artist", "test title", self.network) # Act / Assert - self.assertNotEqual(track1, track2) + assert track1 != track2 def test_track_get_correction(self): # Arrange @@ -238,7 +238,7 @@ def test_track_get_correction(self): corrected_track_name = track.get_correction() # Assert - self.assertEqual(corrected_track_name, "Mr. Brownstone") + assert corrected_track_name == "Mr. Brownstone" def test_track_with_no_mbid(self): # Arrange @@ -248,8 +248,4 @@ def test_track_with_no_mbid(self): mbid = track.get_mbid() # Assert - self.assertIsNone(mbid) - - -if __name__ == "__main__": - unittest.main(failfast=True) + assert mbid is None diff --git a/tests/test_user.py b/tests/test_user.py index e3715296..b0ae8989 100755 --- a/tests/test_user.py +++ b/tests/test_user.py @@ -5,7 +5,7 @@ import calendar import datetime as dt import os -import unittest +import re import warnings import pylast @@ -33,7 +33,7 @@ def test_str(self): string = str(user) # Assert - self.assertEqual(string, "RJ") + assert string == "RJ" def test_equality(self): # Arrange @@ -43,9 +43,9 @@ def test_equality(self): not_a_user = self.network # Act / Assert - self.assertEqual(user_1a, user_1b) - self.assertNotEqual(user_1a, user_2) - self.assertNotEqual(user_1a, not_a_user) + assert user_1a == user_1b + assert user_1a != user_2 + assert user_1a != not_a_user def test_get_name(self): # Arrange @@ -55,7 +55,7 @@ def test_get_name(self): name = user.get_name(properly_capitalized=True) # Assert - self.assertEqual(name, "RJ") + assert name == "RJ" def test_get_user_registration(self): # Arrange @@ -67,11 +67,11 @@ def test_get_user_registration(self): # Assert if int(registered): # Last.fm API broken? Used to be yyyy-mm-dd not Unix timestamp - self.assertEqual(registered, "1037793040") + assert registered == "1037793040" else: # Old way # Just check date because of timezones - self.assertIn("2002-11-20 ", registered) + assert "2002-11-20 " in registered def test_get_user_unixtime_registration(self): # Arrange @@ -82,7 +82,7 @@ def test_get_user_unixtime_registration(self): # Assert # Just check date because of timezones - self.assertEqual(unixtime_registered, 1037793040) + assert unixtime_registered == 1037793040 def test_get_countryless_user(self): # Arrange @@ -93,7 +93,7 @@ def test_get_countryless_user(self): country = lastfm_user.get_country() # Assert - self.assertIsNone(country) + assert country is None def test_user_get_country(self): # Arrange @@ -103,7 +103,7 @@ def test_user_get_country(self): country = lastfm_user.get_country() # Assert - self.assertEqual(str(country), "United Kingdom") + assert str(country) == "United Kingdom" def test_user_equals_none(self): # Arrange @@ -113,7 +113,7 @@ def test_user_equals_none(self): value = lastfm_user is None # Assert - self.assertFalse(value) + assert not value def test_user_not_equal_to_none(self): # Arrange @@ -123,7 +123,7 @@ def test_user_not_equal_to_none(self): value = lastfm_user is not None # Assert - self.assertTrue(value) + assert value def test_now_playing_user_with_no_scrobbles(self): # Arrange @@ -134,7 +134,7 @@ def test_now_playing_user_with_no_scrobbles(self): current_track = user.get_now_playing() # Assert - self.assertIsNone(current_track) + assert current_track is None def test_love_limits(self): # Arrange @@ -142,10 +142,10 @@ def test_love_limits(self): user = self.network.get_user("test-user") # Act/Assert - self.assertEqual(len(user.get_loved_tracks(limit=20)), 20) - self.assertLessEqual(len(user.get_loved_tracks(limit=100)), 100) - self.assertGreaterEqual(len(user.get_loved_tracks(limit=None)), 23) - self.assertGreaterEqual(len(user.get_loved_tracks(limit=0)), 23) + assert len(user.get_loved_tracks(limit=20)) == 20 + assert len(user.get_loved_tracks(limit=100)) <= 100 + assert len(user.get_loved_tracks(limit=None)) >= 23 + assert len(user.get_loved_tracks(limit=0)) >= 23 def test_user_is_hashable(self): # Arrange @@ -183,7 +183,7 @@ def test_pickle(self): os.remove(filename) # Assert - self.assertEqual(lastfm_user, loaded_user) + assert lastfm_user == loaded_user @pytest.mark.xfail def test_cacheable_user(self): @@ -217,10 +217,10 @@ def test_user_top_tracks(self): def helper_assert_chart(self, chart, expected_type): # Assert - self.assertIsNotNone(chart) - self.assertGreater(len(chart), 0) - self.assertIsInstance(chart[0], pylast.TopItem) - self.assertIsInstance(chart[0].item, expected_type) + assert chart is not None + assert len(chart) > 0 + assert isinstance(chart[0], pylast.TopItem) + assert isinstance(chart[0].item, expected_type) def helper_get_assert_charts(self, thing, date): # Arrange @@ -241,10 +241,10 @@ def helper_get_assert_charts(self, thing, date): def helper_dates_valid(self, dates): # Assert - self.assertGreaterEqual(len(dates), 1) - self.assertIsInstance(dates[0], tuple) + assert len(dates) >= 1 + assert isinstance(dates[0], tuple) (start, end) = dates[0] - self.assertLess(start, end) + assert start < end def test_user_charts(self): # Arrange @@ -276,8 +276,8 @@ def test_user_top_albums(self): self.helper_only_one_thing_in_top_list(albums, pylast.Album) top_album = albums[0].item - self.assertTrue(len(top_album.info["image"])) - self.assertRegex(top_album.info["image"][pylast.SIZE_LARGE], r"^http.+$") + assert len(top_album.info["image"]) + assert re.search(r"^http.+$", top_album.info["image"][pylast.SIZE_LARGE]) def test_user_tagged_artists(self): # Arrange @@ -328,8 +328,8 @@ def test_user_subscriber(self): non_subscriber_is_subscriber = non_subscriber.is_subscriber() # Assert - self.assertTrue(subscriber_is_subscriber) - self.assertFalse(non_subscriber_is_subscriber) + assert subscriber_is_subscriber + assert not non_subscriber_is_subscriber def test_user_get_image(self): # Arrange @@ -349,7 +349,7 @@ def test_user_get_library(self): library = user.get_library() # Assert - self.assertIsInstance(library, pylast.Library) + assert isinstance(library, pylast.Library) def test_get_recent_tracks_from_to(self): # Arrange @@ -364,9 +364,9 @@ def test_get_recent_tracks_from_to(self): tracks = lastfm_user.get_recent_tracks(time_from=utc_start, time_to=utc_end) # Assert - self.assertEqual(len(tracks), 1) - self.assertEqual(str(tracks[0].track.artist), "Johnny Cash") - self.assertEqual(str(tracks[0].track.title), "Ring of Fire") + assert len(tracks) == 1 + assert str(tracks[0].track.artist) == "Johnny Cash" + assert str(tracks[0].track.title) == "Ring of Fire" def test_get_recent_tracks_limit_none(self): # Arrange @@ -383,9 +383,9 @@ def test_get_recent_tracks_limit_none(self): ) # Assert - self.assertEqual(len(tracks), 11) - self.assertEqual(str(tracks[0].track.artist), "Seun Kuti & Egypt 80") - self.assertEqual(str(tracks[0].track.title), "Struggles Sounds") + assert len(tracks) == 11 + assert str(tracks[0].track.artist) == "Seun Kuti & Egypt 80" + assert str(tracks[0].track.title) == "Struggles Sounds" def test_get_playcount(self): # Arrange @@ -395,7 +395,7 @@ def test_get_playcount(self): playcount = user.get_playcount() # Assert - self.assertGreaterEqual(playcount, 128387) + assert playcount >= 128387 def test_get_image(self): # Arrange @@ -416,7 +416,7 @@ def test_get_url(self): url = user.get_url() # Assert - self.assertEqual(url, "https://www.last.fm/user/rj") + assert url == "https://www.last.fm/user/rj" def test_get_weekly_artist_charts(self): # Arrange @@ -427,8 +427,8 @@ def test_get_weekly_artist_charts(self): artist, weight = charts[0] # Assert - self.assertIsNotNone(artist) - self.assertIsInstance(artist.network, pylast.LastFMNetwork) + assert artist is not None + assert isinstance(artist.network, pylast.LastFMNetwork) def test_get_weekly_track_charts(self): # Arrange @@ -439,8 +439,8 @@ def test_get_weekly_track_charts(self): track, weight = charts[0] # Assert - self.assertIsNotNone(track) - self.assertIsInstance(track.network, pylast.LastFMNetwork) + assert track is not None + assert isinstance(track.network, pylast.LastFMNetwork) def test_user_get_track_scrobbles(self): # Arrange @@ -452,9 +452,9 @@ def test_user_get_track_scrobbles(self): scrobbles = user.get_track_scrobbles(artist, title) # Assert - self.assertGreater(len(scrobbles), 0) - self.assertEqual(str(scrobbles[0].track.artist), "France Gall") - self.assertEqual(scrobbles[0].track.title, "Laisse Tomber Les Filles") + assert len(scrobbles) > 0 + assert str(scrobbles[0].track.artist) == "France Gall" + assert scrobbles[0].track.title == "Laisse Tomber Les Filles" def test_cacheable_user_get_track_scrobbles(self): # Arrange @@ -475,12 +475,9 @@ def test_get_artist_tracks_deprecated(self): lastfm_user = self.network.get_user(self.username) # Act / Assert - with warnings.catch_warnings(), self.assertRaisesRegex( - pylast.WSError, "Deprecated - This type of request is no longer supported" + with warnings.catch_warnings(), pytest.raises( + pylast.WSError, + match="Deprecated - This type of request is no longer supported", ): warnings.filterwarnings("ignore", category=DeprecationWarning) lastfm_user.get_artist_tracks(artist="Test Artist") - - -if __name__ == "__main__": - unittest.main(failfast=True) From d467e2ceb7eed1e1b8b52b19ffed8d59e3d60ea1 Mon Sep 17 00:00:00 2001 From: Hugo Date: Mon, 1 Jun 2020 21:45:11 +0300 Subject: [PATCH 5/6] If we already have the album, return early --- src/pylast/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pylast/__init__.py b/src/pylast/__init__.py index 4befdb7a..21e21404 100644 --- a/src/pylast/__init__.py +++ b/src/pylast/__init__.py @@ -2128,6 +2128,8 @@ def is_fulltrack_available(self): def get_album(self): """Returns the album object of this track.""" + if "album" in self.info and self.info["album"] is not None: + return Album(self.artist, self.info["album"], self.network) doc = self._request(self.ws_prefix + ".getInfo", True) From 6f6285716450dd7bb16b3bb9c378bffeb865bcab Mon Sep 17 00:00:00 2001 From: Hugo Date: Tue, 2 Jun 2020 16:02:26 +0300 Subject: [PATCH 6/6] Add test for get_album() changes --- tests/test_network.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_network.py b/tests/test_network.py index 85362a34..8c84760e 100755 --- a/tests/test_network.py +++ b/tests/test_network.py @@ -49,6 +49,7 @@ def test_update_now_playing(self): assert str(current_track.title).lower() == "test title" assert str(current_track.artist).lower() == "test artist" assert current_track.info["album"] == "Test Album" + assert current_track.get_album().title == "Test Album" assert len(current_track.info["image"]) assert re.search(r"^http.+$", current_track.info["image"][pylast.SIZE_LARGE])